C++11 线程是可连接的,但 join() 会引发异常

Posted

技术标签:

【中文标题】C++11 线程是可连接的,但 join() 会引发异常【英文标题】:C++11 Thread is joinable but join() raises an exception 【发布时间】:2016-08-09 10:41:43 【问题描述】:

我对 C++11 线程有一个奇怪的问题。 不幸的是,我无法粘贴完整的示例(考虑到复杂性),也无法在更简单的示例中复制该问题。

所以问题是我有一个正在运行的线程(没有调用join 也没有调用detach)。 在某个时候,另一个线程想要停止这个线程。该实现简单地将布尔变量设置为 false,并调用join 以等待线程终止。

嗯,问题是连接。 我检查了当前线程(调用连接)与连接线程不同,joinable() 返回 true。 尽管如此,还是会发生此异常:

libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: thread::join failed: No such process

这发生在 macOS 10.11 上,但我的一位同事在 linux 上对其进行了测试,但没有发生。

有什么线索吗?

【问题讨论】:

你说代码很复杂,你确定 join 没有在其他地方调用过吗?尝试添加更多调试日志记录和跟踪以查看发生了什么。 @JoachimPileborg 不会 joinable 返回 false 如果线程已经加入? 是的,所以可能还有其他问题。由于您无法在 MCVE 中复制它,因此真的不可能说什么,但问题更有可能是您的代码而不是标准库。尝试使用诸如Valgrind 或类似的内存调试器,看看你是否做了一些你不应该做的事情。如果很难在调试器中单步执行代码,那么调试/跟踪日志记录仍然是一个好主意。 是的.. 我知道没有一个简单的例子很难说些什么。我希望得到一些提示。我会继续调试 我在使用 gcc 4.9 时遇到了同样的问题。该线程是可加入的,但在加入时我没有这样的进程(ESRCH,int=3) 【参考方案1】:

如果您在父进程中创建额外线程后调用 fork(),可能会发生这种情况。子进程与父进程不同的一件重要事情是子进程只有一个线程。

所以所有认为有线程的 C++ 代码都会被愚弄,并且 join() 会抛出 “没有这样的过程”。在这种情况下,因为本机调用将返回 ESRCH。

你不应该在调用 fork() 之前创建线程。

【讨论】:

或(我希望)在您新创建的进程中认为所有先前的线程都不存在。顺便说一句:在任何地方都不鼓励分叉和多线程:((例如linuxprogrammingblog.com/…)

以上是关于C++11 线程是可连接的,但 join() 会引发异常的主要内容,如果未能解决你的问题,请参考以下文章

❥关于C++之多线程┆<thread>join()detach()

C++11多线程中的detach()join()joinable()

Boost Thread - 创建一个没有 join() 的线程

C++11多线程,线程对象(thread对象)joinable()join()detach()左值智能指针

C++11多线程,线程对象(thread对象)joinable()join()detach()左值智能指针

为啥 c++ 线程是可移动的但不可复制的?