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()左值智能指针