我已经通过“CreateThread”函数创建了一个线程。Windows C++ - 用CloseHandle关闭线程
在这个线程中,我有'while(true)'循环(读取输入)。
现在,当我想关闭线程时,我使用'CloseHandle'函数。
这是正确的做法吗?或者我应该退出'while(true)'循环,然后使用'CloseHandle'函数?
感谢
我已经通过“CreateThread”函数创建了一个线程。Windows C++ - 用CloseHandle关闭线程
在这个线程中,我有'while(true)'循环(读取输入)。
现在,当我想关闭线程时,我使用'CloseHandle'函数。
这是正确的做法吗?或者我应该退出'while(true)'循环,然后使用'CloseHandle'函数?
感谢
CloseHandle()不会销毁,终止或supspend线程,它只会销毁句柄本身(因此您没有句柄来终止线程或等待它)。线程继续正常工作(我已经在很多情况下使用了它),停止它的唯一方法是退出线程函数(ThreadProc()),或者终止它。
一般来说,这(调用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);
最好的事情是仔细阅读文档。 Win32 API有充分的文档记录。
从MSDN on CreateThread in the Remarks section它说
线程执行开始于由lpStartAddr 参数指定的功能。如果此函数返回,则使用DWORD返回值来 终止隐式调用ExitThread函数中的线程。 使用GetExitCodeThread函数获取线程的返回值。
接下来,你应该让线程入口函数完成它的工作并完成。即退出将返回线程入口函数的循环。
@ kakush,如果你去'ShouldExit',确保你声明它为'volatile'。否则,它可能无法做到这一点。 – eran
@eran,你说得对。 –
@eran:对于Visual C++编译器,'volatile'技巧只适用*。它可能不适用于其他编译器。 –