GetExitCodeThread() 和 ExitThread()
有关线程函数 GetExitCodeThread() 和 ExitThread() 函数: GetExitCodeThread() 功能:获取一个结束线程的返回值 函数原形: BOOL GetExitCodeThread( HANDLE hThread, LPDWORD lpExitCode); 参数: hThread 指向欲获取返回值的线程对象的句柄 返回值:函数执行成功则返回非0值,否则返回 0(FALSE) IN MSDN: RemarksIf the specified thread has not terminated, the termination status returned is STILL_ACTIVE. If the thread has terminated, the termination status returned may be one of the following:
Warning 最后一句: 如果一个线程将 STILL_ACTIVE 作为错误码返回,则检测该线程的应用程序将陷入死循环。 在翻译版书上是这样说的: (Pg: 64) GetExitCodeThread() 将传回线程函数的返回值,然而GetExitCodeThread() 的一个糟糕行为是,当线程还在进行,尚未有所谓的结束代码时,它会传回TRUE表示成功,如果 问题是: GetExitCodeThread() 的返回值应该是 TRUE 或者 FALSE, 尽管 BOOL 实际上是 typedef int BOOL, 即 GetExitCodeThread() 的返回值只表示该函数本身执行是否成功并不是说对应线程如果结束了GetExitCodeThread() 函数就必须返回其结束代码,线程是否结束与该函数的返回值根本就是两码事,GetExitCodeThread() 函数返回 FALSE 的唯一情况应该是它无法确定其检测线程的状态.而候捷这里却以其返回值来判断被检测线程是否结束,并说GetExitCodeThread() 的返回值是一种" 糟糕的行为" ,这很没道理,该函数设计的目的就是获取一个线程结束时的返回值,本来就不是用来检测一个线程是否结束,当然如果能够保证线程不将 STILL_ACTIVE 作为错误码返回也可以用来检测线程是否结束.就像该书上的代码如下: #define WIN32_LEAN_AND_MEAN // 排除一些不太常用的 API, 加速生成过程
int main(){ hThread1 = CreateThread(NULL,0,GetMax,(LPVOID)1,0,&dwThId); hThread2 = CreateThread(NULL,0,GetMax,(LPVOID)2,0,&dwThId); for(;;){ CloseHandle(hThread1); // 关闭线程句柄并不影响线程的执行 return EXIT_SUCCESS; 建议不要用该函数来检测线程是否结束. 另外就是 ExitThread() 函数: 功能: 提前结束一个线程 原型: VOID ExitThread(DWORD dwExitCode) 参数: dwExitCode 线程的返回值 函数行为: 该函数最好用于 C 程序里,在 C++里调用该函数结束线程,并不会调用有关对象的析构函数以及其它的自动清理动作.当在线程里调用该函数后,线程的堆栈将被收回,所有未完成的I/O操作将被取消,于其连接的动态连接库也被分离.如果该线程是程序里的最后一个线程,则程序也随之结束.线程对象将发出一个信号,释放所有等待该线程结束的线程.一个线程结束了,并不需要释放与之相关的线程对象句柄,当与线程对象句柄相关的所有线程结束后,线程对象句柄将被删除. 以上是MSDN里的,有的没写了,主要问题是,候捷翻译书上说(Pg: 67)
而后面又说:
这前后矛盾的话相差就是几行文字,看了觉得不提出来心里就不爽,难到"所有线程"不能包括"worker线程"吗 ??? (注:worker线程是指与 UI 无关的纯计算线程) 下面的程序就否定了,在主线程里调用ExitThread()函数使得所有线程都被迫结束得观点:
#include <stdio.h> DWORD WINAPI ThreadProc(LPVOID); DWORD WINAPI ThreadProc(LPVOID p){ int main(){ hThread = CreateThread(NULL,0,ThreadProc,0,0,&dwThId); return EXIT_SUCCESS; |