zoukankan      html  css  js  c++  java
  • [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;
    }

    结果图:

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

    结果图:
  • 相关阅读:
    数组常用函数
    数组游标操作
    PHP中 字符串 常用函数
    mysqli扩展库的预处理技术 mysqli stmt
    mysql的事务处理
    mysqli的增强功能
    mysql扩展库-1
    抽象类与接口
    iOS判断字符串是否包含表情字符
    iOS8 UITableView 分割条设置separator intent = 0 不起作用
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3049912.html
Copyright © 2011-2022 走看看