线程同步的四种方式(MFC线程同步4种方式)



<1>使用互斥对象Mutex实现线程同步

  1. CMutex mutex;               //互斥量对象  
  2. int g_data = 0;             //全局资源  
  3. static HANDLE  g_ReadHnd;   //读线程句柄  
  4. static HANDLE  g_WriteHnd;   //写线程句柄  
  5.   
  6. ///  
  7. UINT ThreadProcWrite(LPVOID param)  //用于写数据的线程,即第一个线程的回调函数  
  8. {  
  9.     CEdit *pedit=(CEdit*)param;  
  10.     while(true)  
  11.     {  
  12.         CString str;  
  13.         CSingleLock singleLock(&mutex);  
  14.         singleLock.Lock();  
  15.         g_data++;   //数据加1  
  16.         str.Format("%d", g_data);  
  17.         pedit->SetWindowText(str);//编辑框显示数据  
  18.         Sleep(1000);  //阻塞线程一定时间  
  19.         singleLock.Unlock();  //互斥量解锁  
  20.     }  
  21.     return 0;  
  22. }  
  23.   
  24.   
  25. /  
  26. UINT ThreadProcRead(LPVOID param)  //用于读数据的线程,即第二个线程的回调函数  
  27. {  
  28.     UINT retval;  
  29.     CEdit *pedit=(CEdit*)param;  
  30.     while(true)  
  31.     {  
  32.         CSingleLock singleLock(&mutex);  
  33.         singleLock.Lock();  
  34.         retval = g_data;      //读数据  
  35.         singleLock.Unlock();  //解锁  
  36.         CString str;  
  37.         str.Format("%d", retval);  
  38.         pedit->SetWindowText(str);//编辑框显示数据    
  39.     }  
  40.     return 0;  
  41. }  
  42.   
  43. ///  
  44. void CMutexThreadSynDlg::OnStarw() //启动写线程  
  45. {  
  46.     // TODO: Add your control notification handler code here  
  47.     CWinThread* pThread;  
  48.     pThread = AfxBeginThread(ThreadProcWrite, &m_WriteEdit);//开始写线程  
  49.     g_WriteHnd = pThread->m_hThread;             //获取写线程句柄  
  50.     GetDlgItem(IDC_STARW)->EnableWindow(false);  //启动按钮无效  
  51.     GetDlgItem(IDC_STOPW)->EnableWindow(true);   //开始按钮生效   
  52. }  
  53.   
  54. //  
  55. void CMutexThreadSynDlg::OnStarr()  //启动读线程  
  56. {  
  57.     // TODO: Add your control notification handler code here  
  58.     CWinThread* pThread;  
  59.     pThread = AfxBeginThread(ThreadProcRead, &m_ReadEdit);//开始读线程  
  60.     g_ReadHnd = pThread->m_hThread;    //获取写线程句柄  
  61.     GetDlgItem(IDC_STARR)->EnableWindow(false);  //启动按钮无效  
  62.     GetDlgItem(IDC_STOPR)->EnableWindow(true);  //停止按钮生效    
  63. }  
  64.   
  65.   
  66. void CMutexThreadSynDlg::OnStopr() //销毁读线程  
  67. {  
  68.     // TODO: Add your control notification handler code here  
  69.       
  70.     CSingleLock singleLock(&mutex);  
  71.     singleLock.Lock();  
  72.     TerminateThread(g_ReadHnd, 0);    //终止读线程  
  73.     singleLock.Unlock();              //释放资源  
  74.     m_ReadEdit.SetWindowText("终止读线程");  
  75.     GetDlgItem(IDC_STARR)->EnableWindow(true);  //启动按钮生效  
  76.     GetDlgItem(IDC_STOPR)->EnableWindow(false);  //停止按钮无效   
  77. }  
  78.   
  79. //  
  80. void CMutexThreadSynDlg::OnStopw() //销毁写线程  
  81. {  
  82.     // TODO: Add your control notification handler code here  
  83.       
  84.     CSingleLock singleLock(&mutex);  
  85.     singleLock.Lock();  
  86.     TerminateThread(g_WriteHnd, 0);            //终止写线程  
  87.     singleLock.Unlock();                       //释放资源   
  88.     m_WriteEdit.SetWindowText("终止写线程");  
  89.     GetDlgItem(IDC_STARW)->EnableWindow(true);  //启动按钮生效  
  90.     GetDlgItem(IDC_STOPW)->EnableWindow(false);  //停止按钮无效   
  91. }  
CMutex mutex;               //互斥量对象
int g_data = 0;             //全局资源
static HANDLE  g_ReadHnd;   //读线程句柄
static HANDLE  g_WriteHnd;   //写线程句柄

///
UINT ThreadProcWrite(LPVOID param)  //用于写数据的线程,即第一个线程的回调函数
{
	CEdit *pedit=(CEdit*)param;
	while(true)
	{
		CString str;
		CSingleLock singleLock(&mutex);
		singleLock.Lock();
		g_data++;   //数据加1
		str.Format("%d", g_data);
		pedit->SetWindowText(str);//编辑框显示数据
		Sleep(1000);  //阻塞线程一定时间
		singleLock.Unlock();  //互斥量解锁
	}
	return 0;
}


/
UINT ThreadProcRead(LPVOID param)  //用于读数据的线程,即第二个线程的回调函数
{
	UINT retval;
	CEdit *pedit=(CEdit*)param;
	while(true)
	{
		CSingleLock singleLock(&mutex);
		singleLock.Lock();
		retval = g_data;      //读数据
		singleLock.Unlock();  //解锁
		CString str;
		str.Format("%d", retval);
		pedit->SetWindowText(str);//编辑框显示数据	
	}
	return 0;
}

///
void CMutexThreadSynDlg::OnStarw() //启动写线程
{
	// TODO: Add your control notification handler code here
	CWinThread* pThread;
	pThread = AfxBeginThread(ThreadProcWrite, &m_WriteEdit);//开始写线程
	g_WriteHnd = pThread->m_hThread;             //获取写线程句柄
	GetDlgItem(IDC_STARW)->EnableWindow(false);  //启动按钮无效
	GetDlgItem(IDC_STOPW)->EnableWindow(true);   //开始按钮生效 
}

//
void CMutexThreadSynDlg::OnStarr()  //启动读线程
{
	// TODO: Add your control notification handler code here
	CWinThread* pThread;
	pThread = AfxBeginThread(ThreadProcRead, &m_ReadEdit);//开始读线程
	g_ReadHnd = pThread->m_hThread;    //获取写线程句柄
	GetDlgItem(IDC_STARR)->EnableWindow(false);  //启动按钮无效
	GetDlgItem(IDC_STOPR)->EnableWindow(true);  //停止按钮生效  
}


void CMutexThreadSynDlg::OnStopr() //销毁读线程
{
	// TODO: Add your control notification handler code here
	
	CSingleLock singleLock(&mutex);
	singleLock.Lock();
	TerminateThread(g_ReadHnd, 0);    //终止读线程
	singleLock.Unlock();              //释放资源
	m_ReadEdit.SetWindowText("终止读线程");
	GetDlgItem(IDC_STARR)->EnableWindow(true);  //启动按钮生效
	GetDlgItem(IDC_STOPR)->EnableWindow(false);  //停止按钮无效 
}

//
void CMutexThreadSynDlg::OnStopw() //销毁写线程
{
	// TODO: Add your control notification handler code here
	
	CSingleLock singleLock(&mutex);
	singleLock.Lock();
	TerminateThread(g_WriteHnd, 0);            //终止写线程
	singleLock.Unlock();                       //释放资源 
	m_WriteEdit.SetWindowText("终止写线程");
	GetDlgItem(IDC_STARW)->EnableWindow(true);  //启动按钮生效
	GetDlgItem(IDC_STOPW)->EnableWindow(false);  //停止按钮无效 
}

<2>使用信号量Semaphore实现线程同步

  1. int thread=0;  
  2. CSemaphore mySemaphore(4,4);  
  3.   
  4. //  
  5. UINT ThreadProc(LPVOID pParam)  
  6. {  
  7.     CEdit* pedit=(CEdit*)pParam;  
  8.     CString str;  
  9.     thread++;  
  10.     str.Format("%d",thread);  
  11.     pedit->SetWindowText(str);  
  12.     CSingleLock singlelock(&mySemaphore);  
  13.     singlelock.Lock();  
  14.     MessageBox(NULL,"信号量控制访问资源线程数","提示",MB_ICONWARNING);  
  15.     thread--;  
  16.     str.Format("%d",thread);  
  17.     pedit->SetWindowText(str);  
  18.     return 0;  
  19. }  
  20.   
  21.   
  22. void CSemaphoreThreadSynDlg::OnCreateThread()   
  23. {  
  24.     // TODO: Add your control notification handler code here  
  25.     CWinThread* pThread=AfxBeginThread(ThreadProc,&m_Edit);  
  26. }  
int thread=0;
CSemaphore mySemaphore(4,4);

//
UINT ThreadProc(LPVOID pParam)
{
	CEdit* pedit=(CEdit*)pParam;
	CString str;
	thread++;
	str.Format("%d",thread);
	pedit->SetWindowText(str);
	CSingleLock singlelock(&mySemaphore);
	singlelock.Lock();
	MessageBox(NULL,"信号量控制访问资源线程数","提示",MB_ICONWARNING);
	thread--;
	str.Format("%d",thread);
	pedit->SetWindowText(str);
	return 0;
}


void CSemaphoreThreadSynDlg::OnCreateThread() 
{
	// TODO: Add your control notification handler code here
	CWinThread* pThread=AfxBeginThread(ThreadProc,&m_Edit);
}

<3>使用临界区对象CritialSection实现线程同步

  1. CCriticalSection g_cs;  //临界区对象  
  2. int g_data = 0;     //全局资源  
  3. static HANDLE  g_ReadHnd;//读线程句柄  
  4. static HANDLE  g_WriteHnd;//写线程句柄  
  5.   
  6. /  
  7. UINT ThreadProcWrite(LPVOID param)  //用于写数据的线程,即第一个线程的回调函数  
  8. {  
  9.     CEdit *pedit=(CEdit*)param;  
  10.     while(true)  
  11.     {  
  12.         CString str;  
  13.         g_cs.Lock();  //临界区锁定共享资源  
  14.         g_data++;   //数据加1  
  15.         str.Format("%d", g_data);  
  16.         pedit->SetWindowText(str);//编辑框显示数据  
  17.         Sleep(1000);  //阻塞线程一定时间  
  18.         g_cs.Unlock();  //临界区解锁  
  19.     }  
  20.     return 0;  
  21. }  
  22.   
  23. //  
  24. UINT ThreadProcRead(LPVOID param)  //用于读数据的线程,即第二个线程的回调函数  
  25. {  
  26.     UINT retval;  
  27.     CEdit *pedit=(CEdit*)param;  
  28.     while(true)  
  29.     {  
  30.         g_cs.Lock();  //锁定共享资源  
  31.         retval = g_data; //读数据  
  32.         g_cs.Unlock();  //解锁  
  33.         CString str;  
  34.         str.Format("%d", retval);  
  35.         pedit->SetWindowText(str);//编辑框显示数据  
  36.           
  37.     }  
  38.     return 0;  
  39. }  
  40.   
  41.   
  42. void CCriticalSecitonThreadSynDlg::OnStarw() //启动写线程  
  43. {  
  44.     // TODO: Add your control notification handler code here  
  45.     CWinThread* pThread;  
  46.     pThread = AfxBeginThread(ThreadProcWrite, &m_WriteEdit);//开始写线程  
  47.     g_WriteHnd = pThread->m_hThread;//获取写线程句柄  
  48.     GetDlgItem(IDC_STARW)->EnableWindow(false);//启动按钮无效  
  49.     GetDlgItem(IDC_STOPW)->EnableWindow(true);//开始按钮生效   
  50. }  
  51.   
  52. ///  
  53. void CCriticalSecitonThreadSynDlg::OnStopr() //销毁读线程  
  54. {  
  55.     // TODO: Add your control notification handler code here  
  56.       
  57.     g_cs.Lock();//锁定资源  
  58.     TerminateThread(g_ReadHnd, 0);//终止读线程  
  59.     g_cs.Unlock();//释放资源  
  60.     m_ReadEdit.SetWindowText("终止读线程");  
  61.     GetDlgItem(IDC_STARR)->EnableWindow(true);//启动按钮生效  
  62.     GetDlgItem(IDC_STOPR)->EnableWindow(false);//停止按钮无效   
  63. }  
  64.   
  65. //  
  66. void CCriticalSecitonThreadSynDlg::OnStopw() //销毁写线程  
  67. {  
  68.     // TODO: Add your control notification handler code here  
  69.       
  70.     g_cs.Lock();//锁定资源  
  71.     TerminateThread(g_WriteHnd, 0);//终止写线程  
  72.     g_cs.Unlock();//释放资源   
  73.     m_WriteEdit.SetWindowText("终止写线程");  
  74.     GetDlgItem(IDC_STARW)->EnableWindow(true);//启动按钮生效  
  75.     GetDlgItem(IDC_STOPW)->EnableWindow(false);//停止按钮无效   
  76. }  
  77.   
  78. ///  
  79. void CCriticalSecitonThreadSynDlg::OnStarr() //启动读线程  
  80. {  
  81.     // TODO: Add your control notification handler code here  
  82.     CWinThread* pThread;  
  83.     pThread = AfxBeginThread(ThreadProcRead, &m_ReadEdit);//开始读线程  
  84.     g_ReadHnd = pThread->m_hThread;//获取写线程句柄  
  85.     GetDlgItem(IDC_STARR)->EnableWindow(false);//启动按钮无效  
  86.     GetDlgItem(IDC_STOPR)->EnableWindow(true);//停止按钮生效    
  87. }  
CCriticalSection g_cs;  //临界区对象
int g_data = 0;     //全局资源
static HANDLE  g_ReadHnd;//读线程句柄
static HANDLE  g_WriteHnd;//写线程句柄

/
UINT ThreadProcWrite(LPVOID param)  //用于写数据的线程,即第一个线程的回调函数
{
	CEdit *pedit=(CEdit*)param;
	while(true)
	{
		CString str;
		g_cs.Lock();  //临界区锁定共享资源
		g_data++;   //数据加1
		str.Format("%d", g_data);
		pedit->SetWindowText(str);//编辑框显示数据
		Sleep(1000);  //阻塞线程一定时间
		g_cs.Unlock();  //临界区解锁
	}
	return 0;
}

//
UINT ThreadProcRead(LPVOID param)  //用于读数据的线程,即第二个线程的回调函数
{
	UINT retval;
	CEdit *pedit=(CEdit*)param;
	while(true)
	{
		g_cs.Lock();  //锁定共享资源
		retval = g_data; //读数据
		g_cs.Unlock();  //解锁
		CString str;
		str.Format("%d", retval);
		pedit->SetWindowText(str);//编辑框显示数据
		
	}
	return 0;
}


void CCriticalSecitonThreadSynDlg::OnStarw() //启动写线程
{
	// TODO: Add your control notification handler code here
	CWinThread* pThread;
	pThread = AfxBeginThread(ThreadProcWrite, &m_WriteEdit);//开始写线程
	g_WriteHnd = pThread->m_hThread;//获取写线程句柄
	GetDlgItem(IDC_STARW)->EnableWindow(false);//启动按钮无效
	GetDlgItem(IDC_STOPW)->EnableWindow(true);//开始按钮生效 
}

///
void CCriticalSecitonThreadSynDlg::OnStopr() //销毁读线程
{
	// TODO: Add your control notification handler code here
	
	g_cs.Lock();//锁定资源
	TerminateThread(g_ReadHnd, 0);//终止读线程
	g_cs.Unlock();//释放资源
	m_ReadEdit.SetWindowText("终止读线程");
	GetDlgItem(IDC_STARR)->EnableWindow(true);//启动按钮生效
	GetDlgItem(IDC_STOPR)->EnableWindow(false);//停止按钮无效 
}

//
void CCriticalSecitonThreadSynDlg::OnStopw() //销毁写线程
{
	// TODO: Add your control notification handler code here
	
	g_cs.Lock();//锁定资源
	TerminateThread(g_WriteHnd, 0);//终止写线程
	g_cs.Unlock();//释放资源 
	m_WriteEdit.SetWindowText("终止写线程");
	GetDlgItem(IDC_STARW)->EnableWindow(true);//启动按钮生效
	GetDlgItem(IDC_STOPW)->EnableWindow(false);//停止按钮无效 
}

///
void CCriticalSecitonThreadSynDlg::OnStarr() //启动读线程
{
	// TODO: Add your control notification handler code here
	CWinThread* pThread;
	pThread = AfxBeginThread(ThreadProcRead, &m_ReadEdit);//开始读线程
	g_ReadHnd = pThread->m_hThread;//获取写线程句柄
	GetDlgItem(IDC_STARR)->EnableWindow(false);//启动按钮无效
	GetDlgItem(IDC_STOPR)->EnableWindow(true);//停止按钮生效  
}

<4>使用CEvent对象实现线程同步

  1. CEvent g_Event;  
  2. char g_str[]="how to use the CEvent synchronization classes";  
  3.   
  4. ///  
  5. UINT ThreadFun(LPVOID pParam)  
  6. {  
  7.     WaitForSingleObject(g_Event.m_hObject,INFINITE);  
  8.     CWnd* pMainWnd=AfxGetMainWnd();  
  9.     if(NULL==pParam)  
  10.     {  
  11.         AfxMessageBox("参数传递出错,线程中止!",MB_OK|MB_ICONERROR);  
  12.         AfxEndThread(2);       /  
  13.     }  
  14.     char* pString=(char*)pParam;  
  15.     while(*pString)  
  16.     {  
  17.         if(*pString>='a'&&*pString<='z')  
  18.         {  
  19.             *pString-=32;  
  20.         }  
  21.         pString++;  
  22.     }  
  23.     g_Event.SetEvent();  
  24.     return 0;  
  25. }  
  26.   
  27. /  
  28. void CEventThreadSynDlg::OnEvent()   
  29. {  
  30.     // TODO: Add your control notification handler code here  
  31.     GetDlgItem(IDC_EVENT)->EnableWindow(FALSE);  
  32.     char* temp=(char*)g_str;  
  33.     int i=0;  
  34.     g_Event.SetEvent();  
  35.     WaitForSingleObject(g_Event.m_hObject,INFINITE);  
  36.     while(*temp)  
  37.     {  
  38.         if(i==5)  
  39.         {  
  40.             char* pStr=g_str;  
  41.             AfxBeginThread(ThreadFun,(LPVOID)pStr);  
  42.         }  
  43.         if(i==7)  
  44.         {  
  45.             g_str[i]='7';  
  46.         }  
  47.         Sleep(10);  
  48.         temp++;  
  49.         i++;  
  50.     }  
  51.     GetDlgItem(IDC_EDIT1)->SetWindowText(CString(g_str));  
  52.     g_Event.SetEvent();  
  53.     WaitForSingleObject(g_Event.m_hObject,INFINITE);  
  54.     GetDlgItem(IDC_EDIT2)->SetWindowText(CString(g_str));  
  55. }  

转自:http://blog.youkuaiyun.com/themagickeyjianan/article/details/9390985

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值