何时调用CloseHandle

When to call CloseHandle?

本文关键字:CloseHandle 调用 何时      更新时间:2023-10-16

我有一个主线程,它接收需要一些时间的操作。所以我创建了一个线程并将作业委托给它。这个执行函数是由主线程在接收作业时调用的。每个作业都实现此执行。

Return_type execute( Arguments_here) {
// if a file read case
DWORD threadId;
HANDLE hThread = CreateThread( 
        NULL,                   // default security attributes
        0,                      // use default stack size  
        MyAsyncFileRead,       // thread function name
        details,          // argument to thread function 
        0,                      // use default creation flags 
        &threadId);   // returns the thread identifier
// else do other work
}

现在,由于我不想在主线程上等待,所以我不调用WaitForSingleObject。[我对windows线程的了解很低。所以如果不需要,请原谅]

如果我等待线程关闭,它就会等待我的主线程。我不想那样做。那么我什么时候调用CloseHandle?

当一个人手头有大约10个作业,创建10个线程,然后等待所有10个线程完成时,等待_for_multiple_objects,然后在每个句柄上调用CloseHandle看起来不错。

但在这种情况下我该怎么办?

[我想这个问题对所有操作系统都有意义,所以也要标记它们。]

如果您真的不在乎等待线程,那么您确实可以在创建线程后立即关闭句柄。

然而,我强烈建议不要那样做。您应该始终等待线程退出(最好是以干净、定义明确的方式)。如果没有提前完成,请等待程序退出时生成的每个线程。总是,没有例外
不要让main不知道其他线程是否仍在运行。如果需要的话,用强硬的方式杀死他们(尽管最好是让他们以可控的方式优雅地离开,然后等待)。

如果等待线程完成,您可能会看到退出时出现奇怪的崩溃情况。或者更糟的是,您可能看不到它们,并且只有用户/客户抱怨配置文件损坏了百分之一(或者更糟糕的是,他们的数据文件)1。现在想象一下,他们能够一步一步地展示他们在做什么,你可以看出他们做的每件事都是正确的,不可能出问题
幸运的是,要弄清楚崩溃是由于仍在运行的工作线程访问某个对象(或全局状态)造成的,该对象刚刚被退出的主线程显式或隐式地释放。

当然,你的立场可能是工作线程在程序完成之前很久就已经退出了,所以为什么要麻烦呢。然而,那是在玩俄罗斯轮盘赌。


1这不是虚构的,但我以前确实看到过一些事情发生。

您可以使用unique_ptr<HANDLE, CloseHandle> threadHandle-假设您有一个合适的位置来存储/放置threadHandle变量。。

或者,如果你实际上并不需要句柄,只需在启动线程后立即关闭它,因为只有当你以后关心线程时,句柄才真正有用。

来自MSDN CreateThread文档:

线程对象将保留在系统中,直到线程已终止,并且通过对的调用关闭了它的所有句柄CloseHandle。

如果在以后的某个阶段需要线程的句柄,则可以始终使用OpenThread来获得"新"句柄。当然,假设你也没有"失去"threadId

当然,正确的C++解决方案是使用std::thread