多线程处理:终止线程

通常导致线程终止的两种情况是:控制函数退出或不允许线程完成运行。 如果字处理器使用后台打印线程,若成功完成打印,则控制函数将正常终止。 但是,如果用户要取消打印,后台打印线程则不得不提前终止。 本主题介绍如何实现每一种情况,以及在终止后如何获取线程的退出代码。

  • 正常线程终止

  • 过早的线程终止

  • 检索线程的退出代码

正常线程终止

对于辅助线程,正常线程终止很简单:退出控制函数并返回表示终止原因的值。 可以使用 AfxEndThread 函数或 return 语句。 一般情况下,0 表示成功完成,但这取决于您自己。

对于用户界面线程,该过程也很简单:从用户界面线程内调用 Windows SDK 中的 PostQuitMessagePostQuitMessage 采用的唯一参数是线程的退出代码。 对于辅助线程,0 通常表示成功完成。

过早的线程终止

过早终止线程几乎一样简单:从线程内调用 AfxEndThread。 将所需的退出代码作为唯一参数传递。 这将停止执行线程、解除对线程堆栈的分配、分离附加到线程的所有 DLL 并从内存中删除线程对象。

必须从要终止的线程内调用 AfxEndThread。 如果要从其他线程终止线程,必须设置两个线程间的通信方法。

检索线程的退出代码

若要获取辅助线程或用户界面线程的退出代码,请调用 GetExitCodeThread 函数。 有关此函数的信息,请参见 Windows SDK。 此函数获取线程(存储在 CWinThread 对象的 m_hThread 数据成员中)的句柄和 DWORD 的地址。

如果线程仍然是活动的,GetExitCodeThreadSTILL_ACTIVE 放置在提供的 DWORD 地址中;否则将退出代码放置在该地址中。

检索 CWinThread 对象的退出代码还需要一步。 默认情况下,当 CWinThread 线程终止时,删除该线程对象。 这意味着不能访问 m_hThread 数据成员,因为 CWinThread 对象不再存在。 若要避免出现这种情况,请执行以下操作之一:

  • 将 m_bAutoDelete 数据成员设置为 FALSE。 这使 CWinThread 对象在线程终止后仍可以继续存在。 然后可以在线程终止后,访问 m_hThread 数据成员。 但是,如果使用此方法,就得销毁 CWinThread 对象,因为框架不会自动删除该对象。 这是首选方法。

  • 单独存储线程的句柄。 创建线程后,(使用 ::DuplicateHandle)将其 m_hThread 数据成员复制到其他变量,并通过该变量访问该成员。 这样,终止后即会自动删除对象,并且仍然可以找到线程终止的原因。 请注意:在可以复制句柄之前,线程不终止。 执行此操作的最安全的方式是将 CREATE_SUSPENDED 传递到 AfxBeginThread,存储句柄,然后通过调用 ResumeThread 继续执行线程。

任一方法都可以使您确定 CWinThread 对象终止的原因。

请参见

参考

_endthread, _endthreadex

_beginthread, _beginthreadex

ExitThread

概念

使用 C++ 和 MFC 进行多线程编程