VC多线程编程学习笔记(二)

VC多线程编程学习笔记(二)

 

六、MFC对多线程的支持

MFC中有两种线程:工作者线程和用户界面线程,前者没有消息循环,后者有自己的消息循环。

我们可以使用全局函数AfxBeginThread()来创建并初始化一个线程的运行,该函数有两种重载形式(直接摘自MSDN,一部分内容做了翻译,):

 

CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );

CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );

Return Value

返回一个指向新线程的指针。

Parameters

pfnThreadProc
指向一个工作者线程的执行函数的指针,不能为NULL,线程函数原型必须为:

UINT MyControllingFunction( LPVOID pParam );

pThreadClass
一个从继承自CWinThread的运行时类对象的指针。这个类定义了被创建的用户线程的启动,运行和退出等,拥有自己的消息循环。

pParam
传给线程函数的一个32位的参数。可以是数值,可以是指向结构的指针,也可以被忽略。

nPriority
新线程的优先级,如果为0的话,则和父线程同级。

nStackSize
新线程的堆栈大小(byte),若0,则和父线程相同。

dwCreateFlags
如果为0,则线程在创建后立刻开始执行。如果为CREATE_SUSPEND,则线程在创建后立刻被挂起;

lpSecurityAttrs
指向一个SECURITY_ATTRIBUTES结构,来指定新线程的安全属性,如果为NULL,则与父线程相同。

Remarks

Call this function to create a new thread. The first form of AfxBeginThread creates a worker thread. The second form creates a user-interface thread.

AfxBeginThread 函数创建了一个新的CWinThread对象,调用了CWinThread的CreateThread函数,开始执行线程,并返回线程指针。

既然最后还是调用了CWinThread::CreateThread函数,我们再来看一下这个函数:

BOOL CreateThread( DWORD dwCreateFlags = 0, UINT nStackSize = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );

Return Value

创建成功返回非0,失败返回0

Parameters

参数的意义和上面两个函数一样。

一般情况下,调用AfxBeginThread()来一次性地创建并启动一个线程,但是也可以通过两步法来创建线程:首先创建CWinThread类的一个对象,然后调用该对象的成员函数CreateThread()来启动该线程。

 

virtual BOOL CWinThread::InitInstance();

  重载该函数以控制用户界面线程实例的初始化。初始化成功则返回非0值,否则返回0。用户界面线程经常重载该函数,工作者线程一般不使用InitInstance()。

virtual int CWinThread::ExitInstance();

  在线程终结前重载该函数进行一些必要的清理工作。该函数返回线程的退出码,0表示执行成功,非0值用来标识各种错误。同InitInstance()成员函数一样,该函数也只适用于用户界面线程。

 

附:

一个简单的使用mfc多线程技术的小例子(使用用户界面线程):

1.    创建一个基于对话框的mfc程序UIThread

2.    新加入一个对话框IDC_UIThreadDlg,关联类为CUITDlg,上面放一个按钮,单击事件函数为:
AfxMessageBox(“单击了用户界面线程对话框上的按钮”);

3.    新建一个线程类CUIThread 继承CWinThread类,在类中重载两个函数

BOOL CUIThread::InitInstance()

{

            m_dlg.Create(IDD_THREADDLG);

      m_dlg.ShowWindow(SW_SHOW);

      return TRUE;

}

 

int CUIThread::ExitInstance()

{

      m_dlg.DestroyWindow();

      return CWinThread::ExitInstance();

}

4.      在主对话框中放一个按钮,加入单击事件,里面只需添加一句:

CWinThread *pThread = AfxBeginThread(RUNTIME_CLASS(CUIThread));

5.最后别忘了在每个类中加入所关联类的头文件,编译即可运行。运行后,每点击一次主对话框上的按钮,便会启动一个支线程,而这个支线程会新建一个对话框并显示。而点击这个支线程对话框上的按钮后,另会有显示“单击了用户界面线程对话框上的按钮”的对话框跳出,充分说明了这个支线程拥有自己的消息循环。 

你可能感兴趣的:(多线程,编程,null,mfc,Parameters,attributes)