在派生类的InitInstance()函数中创建用户界面
创建和启动用户界面线程AfxBeginThread
新建一个基于对话框的MFC应用程序,拖放一个List Box控件并为之绑定一个控件类型的变量:m_wndListBox, 添加一个"工作者线程"按钮和一个"用户界面线程"用来创建和启动工作者线程和用户界面线程。
界面如下:
工作者线程相关代码:
// 定义一个线程函数 UINT WorkProc (LPVOID pParam) { CMFCThreadDlg *pDlg = (CMFCThreadDlg*)pParam; for (int i = 0; i < 100; ++i) { pDlg->m_wndListBox.AddString ("Hello Worker!"); Sleep (100); } return 0; } void CMFCThreadDlg::OnBtnWorker() {// "工作者线程"按钮响应函数 // TODO: Add your control notification handler code here // 创建和启动工作者线程, 把主对话框的this指针传递进去是为了在线程函数中使用对话框类的成员 AfxBeginThread (WorkProc, this); }
用户界面线程:
右键工程,New Class ,注意父类选择:CWinThread, 这里类名为:CMyThread
为了创建我们的用户界面, 新建一个对话框资源并用类向导生成对应的对话框类,这里名为:CMyDlg
然后来到我们刚新建的线程类的InitInstance()函数中创建我们的用户界面:
#include "MyDlg.h" BOOL CMyThread::InitInstance() { // TODO: perform and per-thread initialization here CMyDlg dlg; // 保存对话框对象地址到线程类的成员变量中 m_pMainWnd = &dlg; dlg.DoModal (); return TRUE; }为“用户界面”按钮添加消息响应事件:
#include "MyThread.h" void CMFCThreadDlg::OnBtnUi() { // TODO: Add your control notification handler code here AfxBeginThread (RUNTIME_CLASS (CMyThread)); }
线程同步:
这里介绍两种同步方式: 使用临界区, 使用信号量
定义临界区变量 :
CCriticalSection sec; // 使用临界区实现同步操作定义信号量变量:
CSemaphore sec (2, 2); // 使用信号量实现同步操作第一个参数指定信号量的初始大小,第二个参数指定信号量同时使用的最大值
测试代码如下:
#include <afxmt.h> //CCriticalSection sec; // 使用临界区实现同步操作 CSemaphore sec (2, 2); // 使用信号量实现同步操作 UINT CallProc (LPVOID pParam) { int i = (int)pParam; CString strMsg; strMsg.Format ("第%d个同学在打电话...", i); sec.Lock (); AfxMessageBox (strMsg); sec.Unlock (); return 0; } void CMFCThread2Dlg::OnButton2() { // TODO: Add your control notification handler code here for (int i = 1; i <= 6; ++i) AfxBeginThread (CallProc, (LPVOID)i); } // 使用同步技术之前 UINT ChatProc (LPVOID pParam) { int i = (int)pParam; CString strMsg; strMsg.Format ("第%d个同学在聊天...", i); AfxMessageBox (strMsg); return 0; } void CMFCThread2Dlg::OnBtnChat() { // TODO: Add your control notification handler code here for (int i = 1; i <= 6; ++i) AfxBeginThread (ChatProc, (LPVOID)i); }