2018-05-15
关于线程函数结束前显式调用_endthreadex
转载自 http://www.xuebuyuan.com/349166.html
1. 本来,MSDN已经明确指出了:
You can call _endthread or _endthreadex explicitly to terminate a thread; however, _endthread or _endthreadex is
called automatically when the thread returns from the routine passed as a parameter to_beginthread or
_beginthreadex. Terminating a thread with a call toendthread or _endthreadex helps ensure proper recovery of
resources allocated for the thread(http://msdn.microsoft.com/en-us/library/vstudio/hw264s73.aspx).
即,线程从线程函数(例程)返回后,将自动调用_endthreadex. 意即不必在线程函数返回前显式调用_endthreadex.
而在示例_beginthreadex函数时,MSDN给出了如下例子(http://msdn.microsoft.com/en-us/library/kdzttdcb(v=VS.80).aspx):
unsigned Counter; unsigned __stdcall SecondThreadFunc( void* pArguments ){ printf( "In second thread...\n" ); while ( Counter < 1000000 ) Counter++;_endthreadex( 0 );return 0;}
2. 到底要不在线程函数前调用_endthreadex呢?
MSDN在对_endthreadex的注解中提到:
_endthread and _endthreadex cause C++ destructors pending in the thread not to be called.
意即在线程中调用_endthreadex,会导致C++对象的析构函数挂起而不被调用。如果在线程函数中生成的对象关乎资源分配,则可能引起资
源不能被正常回收(destructor不被调用)。
相关资料:
而如果非要用怎么办?
如下例(http://blog.chinaunix.net/uid-406135-id-3421540.html):
在MSDN的示例中,线程函数结束都有
_endthreadex( 0 );
return 0;
以前,我一直不加_endthreadex( 0 ),因为觉得它很丑很冗余,MSDN上如是说:
_endthread or _endthreadex is called automatically when the thread returns from the routine passed as a parameter.
也就是它屁用没有,假如我写成:
_endthreadex( 0 );
return 1;
还会引起歧义。
今日我一时兴起,在return前加上了 _endthreadex( 0 ),然后就报内存泄露,因为它中止线程前不会析构局部变量。
于是将代码改为:
unsigned __stdcall foo( void* p )
{
{
//这里是执行代码
}
_endthreadex( 0 );
return 0;
}
也就是加了个似乎没用的{}。