实例——CCriticalSection临界区
头文件关键代码:
// MFCCriticalSectionDlg.h : 头文件 #pragma once #define WM_MSG WM_USER+1 typedef struct THREAD_PARAM { HWND hWnd; int nData; CCriticalSection* pCriticalSection; }_THREAD_PARAM; UINT ThreadFun1(LPVOID pParam); UINT ThreadFun2(LPVOID pParam);
cpp文件关键代码:
//MFCCriticalSectionDlg.cpp : 实现文件 CMFCCriticalSectionDlg::CMFCCriticalSectionDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CMFCCriticalSectionDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); //成员变量 // CWinThread* pThread1; // CWinThread* pThread2; // THREAD_PARAM mThreadParam; pThread1=NULL; pThread2=NULL; mThreadParam.hWnd=NULL; mThreadParam.nData=0; mThreadParam.pCriticalSection=new CCriticalSection; //存取或者释放一个CCriticalSection对象,要先建立一个CSiingleLock对象,并调用它的Lock和UnLock成员函数。如果CCriticalSection对象是独占使用的,需要调用它的UnLock成员函数以释放对它的占用。 } CMFCCriticalSectionDlg::~CMFCCriticalSectionDlg() { if (pThread1) { WaitForSingleObject(pThread1->m_hThread,INFINITE); delete pThread1; pThread1=NULL; } if (pThread2) { WaitForSingleObject(pThread2->m_hThread,INFINITE); delete pThread2; pThread2=NULL; } if (mThreadParam.pCriticalSection) { delete mThreadParam.pCriticalSection; mThreadParam.pCriticalSection=NULL; } } //WM_MSG消息函数 LRESULT CMFCCriticalSectionDlg::OnMsgFun(WPARAM wParam,LPARAM lParam) { SetDlgItemInt(IDC_EDIT_DATA,mThreadParam.nData); return 0; } //启动线程按钮事件 void CMFCCriticalSectionDlg::OnBnClickedButtonStart() { if (pThread1) { DWORD exitCode=0; if (::GetExitCodeThread(pThread1->m_hThread,&exitCode)) { if (exitCode == STILL_ACTIVE) { AfxMessageBox(_T("线程1已经启动。")); return; } else { delete pThread1; pThread1=NULL; } } } if (pThread2) { DWORD exitCode=0; if (::GetExitCodeThread(pThread2->m_hThread,&exitCode)) { if (exitCode == STILL_ACTIVE) { AfxMessageBox(_T("线程2已经启动。")); return; } else { delete pThread2; pThread2=NULL; } } } mThreadParam.hWnd=m_hWnd; pThread1=AfxBeginThread(ThreadFun1,&mThreadParam,THREAD_PRIORITY_ABOVE_NORMAL,0,CREATE_SUSPENDED); pThread2=AfxBeginThread(ThreadFun2,&mThreadParam,THREAD_PRIORITY_ABOVE_NORMAL,0,CREATE_SUSPENDED); pThread1->m_bAutoDelete=FALSE; pThread2->m_bAutoDelete=FALSE; pThread1->ResumeThread(); pThread2->ResumeThread(); } //线程函数1 UINT ThreadFun1(LPVOID pParam) { THREAD_PARAM* pThreadParam=(THREAD_PARAM*)pParam; pThreadParam->pCriticalSection->Lock(); for (int i=0;i<10;i++) { pThreadParam->nData++; ::PostMessage(pThreadParam->hWnd,WM_MSG,0,0); Sleep(200); } pThreadParam->pCriticalSection->Unlock(); return 0; } //线程函数2 UINT ThreadFun2(LPVOID pParam) { THREAD_PARAM* pThreadParam=(THREAD_PARAM*)pParam; pThreadParam->pCriticalSection->Lock(); for (int i=0;i<10;i++) { pThreadParam->nData--; ::PostMessage(pThreadParam->hWnd,WM_MSG,0,0); Sleep(200); } pThreadParam->pCriticalSection->Unlock(); return 0; }
结果图:
实例——CSemaphore信号量
头文件关键代码:
// MFCSemaphoreDlg.h : 头文件 #pragma once #define WM_MSG WM_USER+1 typedef struct THREAD_PARAM { HWND hWnd; int nData; CSemaphore* pSemaphore; }_THREAD_PARAM; UINT ThreadFun(LPVOID pParam);
cpp文件关键代码:
// MFCSemaphoreDlg.cpp : 实现文件 CMFCSemaphoreDlg::CMFCSemaphoreDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CMFCSemaphoreDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); //成员变量 //THREAD_PARAM mThreadParam; //CObArray mThreadArray; mThreadParam.nData=0; mThreadParam.pSemaphore=new CSemaphore(2,2);//连续单击多次只会增加20次,若:CSemaphore(1,2)连续单击多次增加10次 /* CSemaphore( LONG lInitialCount = 1, LONG lMaxCount = 1, LPCTSTR pstrName= NULL, LPSECURITY_ATTRIBUTES lpsaAttributes = NULL); 参数: lInitialCount 信号的初始使用计数。必须是大于或等于0,并且小于或等于lMaxCount。 lMaxCount 信号的使用计数的最大值。必须大于0。 pstrName 信号的名字。 lpsaAttributes 此信号对象的安全标志。有关这个结构的详细描述,参见“Win32 SDK程序员参考”中的SECURITY_ATTRIBUTES。 说明: 此成员函数用来构造一个有名字或没有名字的CSemaphore对象。要访问或释放一个CSemaphore对象,可以创建一个CMultiLock或CSingleLock对象,并调用它们的Lock和Unlock函数。 */ } CMFCSemaphoreDlg::~CMFCSemaphoreDlg() { int count=mThreadArray.GetCount(); for (int i=0;i<mThreadArray.GetCount();i++) { CWinThread* pThread=(CWinThread*)mThreadArray.GetAt(i); if (pThread) { ::WaitForSingleObject(pThread->m_hThread,INFINITE);//等待线程结束 delete pThread; pThread=NULL; } } mThreadArray.RemoveAll(); if (mThreadParam.pSemaphore) { delete mThreadParam.pSemaphore; mThreadParam.pSemaphore=NULL; } } //WM_MSG消息函数 LRESULT CMFCSemaphoreDlg::OnMsgFun(WPARAM wParam,LPARAM lParam) { SetDlgItemInt(IDC_EDIT_DATA,mThreadParam.nData); return 0; } //启动线程按钮事件 void CMFCSemaphoreDlg::OnBnClickedButtonStart() { mThreadParam.hWnd=m_hWnd; CWinThread* pThread=AfxBeginThread(ThreadFun,&mThreadParam,THREAD_PRIORITY_ABOVE_NORMAL,0,CREATE_SUSPENDED);//启动线程,初始为挂起状态 pthread 0x006ecd68 pro 0x01253700 mThreadArray.Add((CObject*)pThread);//将线程指针添加到数组中 pThread->m_bAutoDelete=FALSE;//线程结束时不自动删除 mdata 0x006e6860 pThread->ResumeThread();//恢复线程运行 } //线程函数 UINT ThreadFun(LPVOID pParam) { THREAD_PARAM* pThreadParam=(THREAD_PARAM*)pParam; CSingleLock singleLock(pThreadParam->pSemaphore); singleLock.Lock(0);//锁定 if (singleLock.IsLocked()) { for (int i=0;i<10;i++) { pThreadParam->nData++; PostMessage(pThreadParam->hWnd,WM_MSG,0,0); Sleep(100); } } singleLock.Unlock();//解锁 return 0; }
结果图: