我有一个主线程接收需要一些时间的操作。所以我创建一个线程并将作业委托给它。主线程在接收作业时调用此执行函数。每个工作都实现了这个执行。
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个线程完成时,那么wait_for_multiple_objects看起来很好,然后在每个句柄上调用CloseHandle。
但在这种情况下我该怎么办?
[我想这个问题对所有操作系统都有用,所以也要标记它们。 ]
答案 0 :(得分:5)
如果你真的不在乎等待线程,你可以在创建线程后立即关闭句柄。
但是,我强烈反对这样做。你应该总是等待线程退出(最好以干净,明确的方式)。如果没有提前完成,请等待程序退出时生成的每个线程。永远,没有例外。
不要让main
不知道其他一些线程是否仍在运行。如果需要的话,以艰难的方式杀死他们(尽管最好让他们以受控的方式优雅地退出,并等待它。)
如果不等待线程完成,您可能会看到奇怪的崩溃退出条件。或者更糟糕的是,您可能不看到它们,并且只有用户/客户抱怨配置文件中的一百个被破坏(或者更糟糕的是,他们的数据文件) 1 。现在想象一下,他们能够逐步展示他们正在做的事情,你可以告诉他们他们做的一切都是正确的,并且没有办法出错。 祝你好运,发现崩溃是由于仍然在运行的工作线程访问某个对象(或全局状态),而这个对象刚刚被现有主线程解除分配,无论是显式还是隐式地由CRT释放。
当然你的立场可能是工作线程在程序完成之前很久就会退出,所以为什么要这么麻烦。然而,那就是玩俄罗斯轮盘赌。
<小时/> 1 这不是虚构的,但我以前见过的事情发生过。
答案 1 :(得分:1)
您可以使用unique_ptr<HANDLE, CloseHandle> threadHandle
- 假设您有一个合适的地方可以存储/放置threadHandle
变量..
或者,如果你实际上不需要句柄,只需在启动线程后立即关闭它,因为句柄只有在你稍后关心线程时才真正有用。
来自MSDN CreateThread
文档:
线程对象保留在系统中,直到线程有 已终止并且所有句柄都已通过调用关闭 CloseHandle的。
如果在稍后阶段你需要一个线程句柄,你总是可以使用OpenThread
来获得一个“新”句柄。当然,假设你并没有“失去”threadId
。
当然,正确的C ++解决方案是使用std::thread
。