[MFC]同步对象——CCriticalSection临界区,CSemaphore信号量

实例——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;

}

结果图: [MFC]同步对象——CCriticalSection临界区,CSemaphore信号量

实例——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;

}

结果图: [MFC]同步对象——CCriticalSection临界区,CSemaphore信号量

 

你可能感兴趣的:(Semaphore)