6

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

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。

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

[我想这个问题与所有操作系统相关,因此也标记它们。]

4

2 回答 2

6

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

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

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

当然,您的立场可能是工作线程将在程序完成之前很久就退出,所以为什么要打扰。但是,那是玩俄罗斯轮盘赌。


1这不是虚构,而是我之前亲眼目睹的事情。

于 2013-08-27T13:54:15.237 回答
1

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

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

来自 MSDNCreateThread文档:

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

如果在稍后阶段您需要线程句柄,您可以随时使用OpenThread来获取“新”句柄。当然,假设您也没有“丢失” threadId

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

于 2013-08-27T12:49:09.857 回答