GetExitCodeThread() 和 ExitThread()--判断线程是否在运行

有关线程函数 GetExitCodeThread() 和 ExitThread()
看了侯捷翻译的 <>,觉得他在翻译这两个函数的时候好象有点和实际不符,我没有该书的原版,不知道是翻译的问题还是原书的问题。
函数: GetExitCodeThread()
功能: 获取一个结束线程的返回值
函数原形: BOOL GetExitCodeThread( HANDLE hThread, LPDWORD lpExitCode);
参数: hThread 指向欲获取返回值的线程对象的句柄
lpExitCode 用于存储线程的返回值
返回值:函数执行成功则返回非0值,否则返回 0(FALSE)
IN MSDN:
Remarks
If 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:
The exit value specified in the ExitThread or TerminateThread function.
The return value from the thread function.
The exit value of the thread's process.
Warning If a thread happens to return STILL_ACTIVE (259) as an error code, applications that test for this value could end up in an infinite loop
最后一句: 如果一个线程将 STILL_ACTIVE 作为错误码返回,则检测该线程的应用程序将陷入死循环。
在翻译版书上是这样说的: (Pg: 64)
GetExitCodeThread() 将传回线程函数的返回值,然而GetExitCodeThread() 的一个
糟糕行为是,当线程还在进行,尚未有所谓的结束代码时,它会传回TRUE表示成功,如果
这样, lpExitCode 指向的内存区域中应该放的时STILL_ACTIVE,你必须小心这种行为
,也就是说你不可能从其返回值中知道"到底是线程还在运行呢,还是它已经结束,但返回
值为 STILL_ACTIVE"
问题是: GetExitCodeThread() 的返回值应该是 TRUE 或者 FALSE, 尽管 BOOL 实际上是 typedef int BOOL, 即 GetExitCodeThread() 的返回值只表示该函数本身执行是否成功并不是说对应线程如果结束了GetExitCodeThread() 函数就必须返回其结束代码,线程是否结束与该函数的返回值根本就是两码事,GetExitCodeThread() 函数返回 FALSE 的唯一情况应该是它无法确定其检测线程的状态.而候捷这里却以其返回值来判断被检测线程是否结束,并说GetExitCodeThread() 的返回值是一种" 糟糕的行为" ,这很没道理,该函数设计的目的就是获取一个线程结束时的返回值,本来就不是用来检测一个线程是否结束,当然如果能够保证线程不将 STILL_ACTIVE 作为错误码返回也可以用来检测线程是否结束.就像该书上的代码如下:
#define WIN32_LEAN_AND_MEAN // 排除一些不太常用的 API, 加速生成过程
#include
#include
#include
#include

DWORD WINAPI GetMax(LPVOID p){
Sleep((DWORD)p*1000+1000);
return (DWORD)p+100;
}
int main(){
HANDLE hThread1;
HANDLE hThread2;
DWORD uExitCode1;
DWORD uExitCode2;
DWORD dwThId;
hThread1

= CreateThread(NULL,0,GetMax,(LPVOID)1,0,&dwThId);
if(hThread1)
puts("start thread1");
hThread2 = CreateThread(NULL,0,GetMax,(LPVOID)2,0,&dwThId);
if(hThread2)
puts("start thread1");
for(;;){
puts("press any key to check thread ...");
_getch();
GetExitCodeThread(hThread1,&uExitCode1);
GetExitCodeThread(hThread2,&uExitCode2);
if(uExitCode1==STILL_ACTIVE)
puts("Thread1 still active");
else
printf("Thread1 over with: %d\n",uExitCode1);
if(uExitCode2==STILL_ACTIVE)
puts("Thread2 still active");
else
printf("Thread2 over with: %d\n",uExitCode2);
if(uExitCode1!=STILL_ACTIVE && uExitCode2!=STILL_ACTIVE)
break;
}
CloseHandle(hThread1); // 关闭线程句柄并不影响线程的执行
CloseHandle(hThread2);
return EXIT_SUCCESS;
}
建议不要用该函数来检测线程是否结束.
另外就是 ExitThread() 函数:
功能: 提前结束一个线程
原型: VOID ExitThread(DWORD dwExitCode)
参数: dwExitCode 线程的返回值
函数行为: 该函数最好用于 C 程序里,在 C++里调用该函数结束线程,并不会调用有关对象的析构函数以及其它的自动清理动作.当在线程里调用该函数后,线程的堆栈将被收回,所有未完成的I/O操作将被取消,于其连接的动态连接库也被分离.如果该线程是程序里的最后一个线程,则程序也随之结束.线程对象将发出一个信号,释放所有等待该线程结束的线程.一个线程结束了,并不需要释放与之相关的线程对象句柄,当与线程对象句柄相关的所有线程结束后,线程对象句柄将被删除.
以上是MSDN里的,有的没写了,主要问题是,候捷翻译书上说(Pg: 67)

" 这一线程的结束(不论是因为返回或因为调用了ExitThread())会使得程序中得所有线程都
被迫结束,程序也因此而结束,其它线程没有机会做清理工作."
而后面又说:

" 在主线程中调用ExitThread()也可以,那会导致线程结束而"worker线程"继续存在"
这前后矛盾的话相差就是几行文字,看了觉得不提出来心里就不爽,难到"所有线程"不能包括"worker线程"吗 ??? (注:worker线程是指与 UI 无关的纯计算线程)
下面的程序就否定了,在主线程里调用ExitThread()函数使得所有线程都被迫结束得观点:

#define WIN32_LEAN_AND_MEAN
#include
#include
#include
#include
DWORD WINAPI ThreadProc(LPVOID);
VOID TestFun();
DWORD WINAPI ThreadProc(LPVOID p){
for(;;)
puts("In ThreadProc()");
return 100;
}
int main(){
HANDLE hThread;
DWORD dwThId;
hThread = CreateThread(NULL,0,ThreadProc,0,0,&dwThId);
if(hThread){
puts("start thread");
CloseHandle(hThread);
}
ExitThread(2);
assert(FALSE);
return EXIT_SUCCESS;
}

相关文档
最新文档