什么时候打电话给CloseHandle?

时间:2013-08-27 12:38:49

标签: c++ multithreading pthreads

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

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。

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

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

2 个答案:

答案 0 :(得分:5)

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

但是,我强烈反对这样做。你应该总是等待线程退出(最好以干净,明确的方式)。如果没有提前完成,请等待程序退出时生成的每个线程。永远,没有例外。
不要让main不知道其他一些线程是否仍在运行。如果需要的话,以艰难的方式杀死他们(尽管最好让他们以受控的方式优雅地退出,并等待它。)

如果等待线程完成,您可能会看到奇怪的崩溃退出条件。或者更糟糕的是,您可能看到它们,并且只有用户/客户抱怨配置文件中的一百个被破坏(或者更糟糕的是,他们的数据文件) 1 。现在想象一下,他们能够逐步展示他们正在做的事情,你可以告诉他们他们做的一切都是正确的,并且没有办法出错。 祝你好运,发现崩溃是由于仍然在运行的工作线程访问某个对象(或全局状态),而这个对象刚刚被现有主线程解除分配,无论是显式还是隐式地由CRT释放。

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

<小时/> 1 这不是虚构的,但我以前见过的事情发生过。

答案 1 :(得分:1)

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

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

来自MSDN CreateThread文档:

  

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

如果在稍后阶段你需要一个线程句柄,你总是可以使用OpenThread来获得一个“新”句柄。当然,假设你并没有“失去”threadId

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