MFC线程分类
工作者线程 - 主要用于后台的耗时的操作,通常没有用户界面。
用户界面线程 - 拥有独立的用户界面
工作者线程的使用
首先实现线程的回调函数,函数原型:UINT MyControllingFunction( LPVOID pParam );
创建和启动工作则线程AfxBeginThread
用户界面线程的使用
添加CWinThread类的派生类
这用于界面线程创建的线程和主对话框是相对对立的线程,独立操作互不影响
工作者线程 - 主要用于后台的耗时的操作,通常没有用户界面。
用户界面线程 - 拥有独立的用户界面
工作者线程的使用
首先实现线程的回调函数,函数原型:UINT MyControllingFunction( LPVOID pParam );
创建和启动工作则线程AfxBeginThread
用户界面线程的使用
添加CWinThread类的派生类
在派生类的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);
}