Windows C++ - 使用 CloseHandle 关闭线程
Posted
技术标签:
【中文标题】Windows C++ - 使用 CloseHandle 关闭线程【英文标题】:Windows C++ - closing thread with CloseHandle 【发布时间】:2012-06-27 12:21:02 【问题描述】:我已经通过“CreateThread”函数创建了一个线程。
在这个线程中,我有一个“while(true)”循环(读取输入)。
现在,当我想关闭线程时,我使用'CloseHandle'函数。
这是正确的做法吗?或者我应该退出 'while(true)' 循环,然后使用 'CloseHandle' 函数?
谢谢
【问题讨论】:
【参考方案1】:CloseHandle() 不会破坏、终止或暂停线程,它只会破坏句柄本身(因此您没有句柄来杀死线程或等待它)。线程继续正常工作(我在很多情况下都使用过),而停止它的唯一方法是退出线程函数(ThreadProc()),或者杀死它。
【讨论】:
注意:要移除线程对象,使用后必须关闭句柄。 Quoted From msdn。 > 关闭线程句柄不会终止关联的线程或删除线程对象。关闭进程句柄不会终止关联的进程或删除进程对象。要删除线程对象,您必须终止线程,然后关闭该线程的所有句柄。【参考方案2】:通常这(调用 TerminateThread)是一件坏事,因为线程可能会分配一些资源(即文件描述符),这些资源在整个进程终止之前将不可用。更重要的是,CloseHandle 不会停止线程。
如果你的线程中有一些冗长的操作,那么至少使用
while(!ShouldExit)
DoOneMoreIteration();
循环。这样,您可以通过将 ShouldExit 设置为 1(或“true”,如果它是 C++ 和 bool 变量)并在该线程的句柄上调用 WaitForSingleObject 来终止线程,以确保它已完成。
对于eran 的评论:ShouldExit 必须声明为'volatile'。
如果您正在等待某些输入(我想是控制台),那么您可以将非阻塞(“重叠”)I/O 与标准输入一起使用。
例如,看到这个问题:Checking Win32 file streams for available input
应该是这样的
HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
while(!ShouldExit)
if(WaitForSingleObject(h, FALSE, SomeTimeoutValue) == WAIT_OBJECT_0)
... use std::cin - it has some input and won't block
为了让事情变得更好(避免 CPU 过载),请使用 WaitForMultipleObjects 并在某些外部事件上中断循环。
/// Global var
HANDLE SomeGlobalEvent;
/// ThreadProc():
HANDLE h[2];
h[0] = GetStdHandle(STD_INPUT_HANDLE);
h[1] = SomeGlobalEvent;
while(true)
DWORD which = WaitForMultipleObjects(2, h, FALSE, SomeTimeoutValue);
if(which == WAIT_OBJECT_0)
... use std::cin - it has some input and won't block
else
if(which == WAIT_OBJECT_1)
// got the termination event
break;
/// "Main" thread:
SomeGlobalEvent = CreateEvent(NULL, false, false, NULL);
HANDLE hThread = _beginthread(ThreadProc, 4096, NULL);
....
/// send termination signal
SetEvent(SomeGlobalEvent);
/// Wait for thread completion
WaitForSingleObject(hThread);
【讨论】:
@kakush,如果您选择ShouldExit
,请确保将其声明为volatile
。否则,它可能无法解决问题。
@eran:volatile
技巧仅适用于 Visual C++ 编译器。它可能不适用于其他编译器。
“其他” - 你的意思是 gcc?会的。
@eran: 'volatile' 适用于嵌入式 IAR 的 C 编译器和 GCC。所以它几乎“无处不在”
@ViktorLatypov,不是我声称 volatile 仅适用于 VC ......但是关于这个主题已经提出了很多问题,并且深入研究细节无论如何超出了这个问题的范围。 【参考方案3】:
最好仔细阅读文档。 Win32 API 有据可查。
来自MSDN on CreateThread in the Remarks section 它说
线程执行从 lpStartAddr 指定的函数开始 范围。如果此函数返回,则 DWORD 返回值用于 在对 ExitThread 函数的隐式调用中终止线程。 使用GetExitCodeThread函数获取线程的返回值。
接下来,你应该让线程入口函数完成它的工作并完成。 IE。退出将返回线程入口函数的循环。
【讨论】:
以上是关于Windows C++ - 使用 CloseHandle 关闭线程的主要内容,如果未能解决你的问题,请参考以下文章
在 windows 中,如何使用 c++ 检查端口是不是免费