实例——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;
}
结果图: