多线程处理:在 MFC 中终止线程
两种正常情况导致线程终止:控制函数退出或线程不允许运行到完成。 如果字处理器使用线程进行后台打印,则打印成功完成后,控制函数将正常终止。 但如果用户需要取消打印,则必须提前终止后台打印线程。 本主题介绍如何实现每种情况,以及如何在线程终止后获取线程的退出代码。
普通线程终止
对于工作线程,普通线程终止很简单:退出控制函数并返回一个表示终止原因的值。 可以使用 AfxEndThread 函数或 return
语句。 通常,0 表示成功完成,但这由你决定。
对于用户界面线程,过程同样简单:从用户界面线程内部调用 Windows SDK 中的 PostQuitMessage。 PostQuitMessage
唯一采用的参数是线程的退出代码。 至于工作线程,0 通常表示成功完成。
线程提前终止
过早终止线程几乎一样简单:从线程内部调用 AfxEndThread。 将所需退出代码作为唯一参数传递。 这会停止执行线程,解除分配线程的堆栈,拆离附加到线程的所有 DLL,并从内存中删除线程对象。
AfxEndThread
必须从要终止的线程中调用。 如果要从另一个线程终止线程,则必须在两个线程之间设置通信方法。
检索线程的退出代码
若要获取工作线程或用户界面线程的退出代码,请调用 GetExitCodeThread 函数。 有关此函数的信息,请参阅 Windows SDK。 此函数获取线程的句柄(存储在 CWinThread
对象的 m_hThread
数据成员中)和一个 DWORD 的地址。
如果线程仍处于活动状态,GetExitCodeThread
会将 STILL_ACTIVE 放置在提供的 DWORD 地址中;否则,退出代码将放置在此地址中。
检索 CWinThread 对象的退出代码需要执行额外的步骤。 默认情况下,当 CWinThread
线程终止时,线程对象将删除。 这意味着将无法访问 m_hThread
数据成员,因为 CWinThread
对象不再存在。 为避免这种情况,请执行下列操作之一:
将
m_bAutoDelete
数据成员设置为 FALSE。 这样,CWinThread
对象就可以在线程终止后继续存在。 然后,可以在线程终止后访问m_hThread
数据成员。 但如果使用此方法,则需负责销毁CWinThread
对象,因为框架不会自动删除该对象。 这是首选方法。单独存储线程的句柄。 创建线程后,将其
m_hThread
数据成员(使用::DuplicateHandle
)复制到另一个变量并通过该变量访问它。 这样当终止发生时,对象会自动删除,而你仍然可以找出线程终止的原因。 请注意,复制句柄之前,线程不会终止。 最安全的方法是将 CREATE_SUSPENDED 传递给 AfxBeginThread,存储句柄,然后通过调用 ResumeThread 继续线程。
利用任一方法都能确定 CWinThread
对象终止的原因。
另请参阅
使用 C++ 和 MFC 进行多线程编程
_endthread、_endthreadex
_beginthread、_beginthreadex
ExitThread