当我的线程退出其句柄时,需要关闭并重置为NULL。而不是在线程闭包事件(例如::WaitForSingleObject( s_hMyThread, TIMEOUT );
)上执行此操作,是否有效关闭句柄并将其重置为线程中的最后一件事,在它返回之前,像这样?
DWORD MyThread( LPVOID pParam )
{
// Does something...
::CloseHandle( s_hMyThread );
s_hMyThread = NULL;
return 0;
}
答案 0 :(得分:4)
你可以做到。
关闭线程句柄不会终止关联的线程或删除线程对象。线程对象保留在系统中,直到线程终止并且通过调用CloseHandle关闭了它的所有句柄。
但是,如果您这样做,如果线程仍在运行,您将无法从应用程序的主线程进行检查,因此,您将无法安全地退出应用程序。还有一件事:如果你的线程以意想不到的方式终止,你就不会释放句柄。
答案 1 :(得分:0)
我不清楚这会使线程对象处于任何等待它的人可以确定发生了什么的状态。根据{{3}}:
线程终止时,线程 对象达到信号状态, 满足任何线程 等待对象。
我怀疑你会得到一个从CreateThread返回的线程句柄,但让创建的线程关闭该句柄。似乎与API设计的意图背道而驰,不是吗?无论它是否有效,我都不会这样做,除非它对你的设计至关重要。
答案 2 :(得分:0)
从技术上讲它是有效的。您可以像任何其他句柄一样关闭该句柄 - 在您喜欢的任何线程中。
但是像你在你的例子中那样关闭线程的句柄并不是一个好主意 - 它通常是没有意义的,它可能是不安全的,因为在访问s_hMyThread变量时没有正确的同步。当然,您可能会对s_hMyThread
变量进行适当的同步,但实际上没有真正意义的代码太难以支持。从这个线程关闭线程的句柄没有任何意义,因为保持线程句柄打开的唯一原因是等待这个线程完成,这自然意味着当线程完成时句柄应该仍然是打开的。
通常好的做法是(1)如果你不必等到线程完成,那么你在创建它之后关闭它的句柄下一行(在CreateThread之后的下一次调用),(2)如果你必须等待这个线程的完成然后,当您知道线程的对象已发出信号(即线程已完成)时,您将关闭线程的句柄。当你真的需要线程处理时我没有看到其他用法。
答案 3 :(得分:0)
阅读你对Lior Kogan的答案后的评论(“有问题的线程设计为一次性处理一些本来会锁定应用程序的东西,所以一旦完成它就完成了。”),在我看来你根本不感兴趣。
为什么你不CloseHandle(CreateThread(...));
呢?这是完全允许的。
或者更好的是,使用_beginthread
和_endthread
。即使你做对该线程感兴趣并且例如想要等待它完成,这也会有效。
从文档:“_ endndread自动关闭线程句柄(而_endthreadex没有)。因此,当使用_beginthread和_endthread时,不要通过调用Win32 CloseHandle API显式关闭线程句柄。”
无需担心关闭任何内容,并且它具有不会因CRT实施失败而泄漏的额外好处。