本例创建两个工作线程,通过使用CCriticalSection类对象,保证同一时刻只有一个线程可以访问临界区对象。
开发过程:
(1) .界面:
(2) 在对话框类的实现文件的顶部定义全局CCriticalSection对象,全局资源和工作线程入口函数
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; }
(3)启动和停止写,读线程实现代码
void CCriticalSectionThreadSynDlg::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 CCriticalSectionThreadSynDlg::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 CCriticalSectionThreadSynDlg::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 CCriticalSectionThreadSynDlg::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); }