首页 理论教育 VisualC++高级编程实例:MFC多线程编程支持

VisualC++高级编程实例:MFC多线程编程支持

时间:2023-11-16 理论教育 版权反馈
【摘要】:用户界面线程一般用于处理独立于其它线程执行之外的用户输入,响应用户及系统所产生的事件和消息等。该函数返回指向被创建的CWinThread类对象的指针。如果为0,则线程和其父线程具有相同的优先级。dwCreateFlags :控制线程创建的标志。CWinThread类的对象描述了进程中线程的执行,进程的主线程执行通常由CWinThread类的导出类CWinApp的派生对象所提供。在MFC中,用户界面线程对象都是CWinThread类的导出类的对象。

VisualC++高级编程实例:MFC多线程编程支持

MFC中有两类线程,分别称之为辅助线程(Worker-Thread)和用户界面线程(User-Interface Thread)。二者的主要区别在于辅助线程没有消息循环,而用户界面线程有自己的消息队列和消息循环。辅助线程没有消息机制,通常用来执行后台计算和维护任务,如冗长的计算过程,打印机的后台打印等。用户界面线程一般用于处理独立于其它线程执行之外的用户输入,响应用户及系统所产生的事件和消息等。

但对于Win32的API编程而言,这两种线程是没有区别的,它们都只需线程的启动地址即可启动线程来执行任务。可以通过线程执行函数的原型来控制线程是否有消息循环。

在MFC中,一般用全局函数AfxBeginThread()来创建并初始化一个线程的运行,该函数有两种重载形式,分别用于创建辅助线程和用户界面线程;调用AfxBeginThread()函数的这两种版本都需要指定参数以指定被创建线程的优先级堆栈大小、创建标志及安全特性等。该函数返回指向被创建的CWinThread类对象的指针。两种版本函数原型及参数说明分别如下:

(1)CWinThread*AfxBeginThread(AFX_THREADPROC pfnThreadProc,

LPVOID pParam, nPriority=THREAD_PRIORITY_NORMAL, UINT=0,

DWORD dwCreateFlags=0, LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL)

pfnThreadProc:指向辅助线程的执行函数的指针,执行函数定义该线程。当进入该函数时,线程启动;退出时,线程终止;该指针不能为NULL,且原型必须声明如下:

UINT ExecutingFunction (LPVOID pParam);

请注意,ExecutingFunction()应返回一个UINT类型的值,用以指明该函数结束的原因。一般情况下,返回0表明执行成功,其它值分别用来代表不同的错误情况。

pParam:在线程启动时传递给其执行函数ExecutingFunction的一个单精度32位参数;执行函数将用某种方式解释该值。它可以是数值,或是指向包括多个参数的结构的指针,甚至可以被忽略。如果该参数是指结构,则不仅可以将数据从调用函数传给线程,也可以从线程回传给调用函数。如果使用这样的结构回传数据,当结果准备好的时候,线程要通知调用函数。

nPriority:线程的优先级。如果为0,则线程和其父线程具有相同的优先级。

nStackSize:线程为自用堆栈分配的地址空间大小,其单位为字节。如果dwStackSize被设为0,则线程的堆栈被设置成与主线程堆栈有相同大小。

dwCreateFlags :控制线程创建的标志。如果为0,则线程在创建后立刻开始执行。如果为CREATE_SUSPEND,则线程在创建后立即被挂起,其挂起状态计数器被置为1。

lpSecurityAttrs:线程的安全属性指针,参见5.2.2小节中CreateThread()函数的参数说明。

辅助线程通常像使用一个普通函数一样使用这个原型,具体做法将在下一节中用实例具体说明。

(2)CWinThread* AfxBeginThread(CRuntimeClass* pThreadClass,

int nPriority= THREAD_PRIORITY_NORMAL, UINT nStackSize = 0,

DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL )

pThreadClass是指向CWinThread的一个导出类的运行时类对象的指针,该导出类定义了被创建的用户界面线程的启动、退出等;其它参数的意义同形式一。使用函数的这个原型时,生成的线程具有消息机制,在以后的例子中我们将发现同主线程的机制几乎一样。下面我们详细说明一下CWinThread类。(www.xing528.com)

CWinThread类的对象描述了进程中线程的执行,进程的主线程执行通常由CWinThread类的导出类CWinApp的派生对象所提供。在MFC中,用户界面线程对象都是CWinThread类的导出类的对象。CWinThread类的数据成员及重要成员函数的用法简要说明如下:

m_bAutoDelete:布尔变量,在创建CWinThread类的对象时置为TURE,对象在线程终结时被系统删除;置为FALSE时,该对象在其相应线程终结时仍然存在。

m_hThread:当前线程的句柄。

m_nThreadID:当前线程的ID。

m_pMainWnd:指向应用程序主窗口的指针。

m_pActiveWnd:指向当前活动窗口的指针。

CWinThread::CWinThread():用于创建CWinThread类的一个对象。

BOOL CWinThread:: CreateThread(DWORD dwCreateFlags = 0,UINT nStackSize = 0,

LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);

该函数中的dwCreateFlags、nStacSize、lpSecurityAttrs参数和API函数CreateThread中的对应参数有相同含义,如果该函数成功执行,则返回非0值,否则返回0。

一般情况下,调用AfxBeginThread()来一次性地创建并启动一个线程,但是也可以通过两步法来创建线程:首先创建CWinThread类的一个对象,然后调用该对象的成员函数CreateThread()来启动该线程。如果程序中要多次终止和启动同一个线程,这种两步的创建方式将非常有用。

virtual BOOL CWinThread::InitInstance();

重载该函数以控制用户界面线程实例的初始化。初始化成功则返回非0值,否则返回0。注意,用户界面线程必须重载该函数,且辅助线程的初始化应调用AfxBeginThread()来完成,不能使用InitInstance()。

virtual int CWinThread::ExitInstance();

在线程终止前重载该函数进行一些必要的清理工作,如释放动态分配的内存,关闭图形设备对象和文件句柄等。该函数返回线程的退出码,0表示执行成功,非0值用来标识各种错误。同InitInstance()成员函数一样,该函数也只适用于用户界面线程。

除了上述数据成员和成员函数,类CWinThread还提供了许多线程控制函数,它们大都是封装Win32 API的同名函数CWinThread的成员函数,具体用法可参考VC++中的联机帮助。

此外,MFC也提供各种线程同步类,如CEvent、CCriticalSection、CMutex、CSemaphore等,这些同步类的具体用法,我们将在后面的实例中讲解。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈