C++中std::thread调用detach()分离后能否重新调用join()?
答案:绝对不可以
首先明确核心规则:std::thread 调用 detach() 后,永远不能再对该对象调用 join(),否则程序会直接抛出异常崩溃。
底层逻辑说明
- 每个
std::thread对象只有两种状态:- 可join状态:对象关联着一个正在运行/待运行的系统线程,此时
joinable()返回true - 空状态:对象不关联任何系统线程,此时
joinable()返回false
- 可join状态:对象关联着一个正在运行/待运行的系统线程,此时
- 调用
detach()的本质是切断线程对象和底层系统线程的绑定关系:底层线程转为后台运行,其资源会在线程执行完成后由系统自动回收,原std::thread对象直接进入空状态。 join()的调用有强制前置校验:只有当对象处于可join状态时调用才合法,对空状态的thread对象(包括已经detach过的、已经join过的、默认构造的空thread)调用join(),都会触发std::system_error异常。
对你给出的示例代码的说明
你贴的代码运行到t.join()这一行时就会直接崩溃,根本无法实现等待工作线程结束的逻辑。
正确实现方式
如果你的需求是「启动工作线程后先让主线程执行其他操作,等其他操作做完再等待工作线程结束」,完全不需要调用detach(),只要把join()的调用时机放到你主线程自定义逻辑的后面即可,修正后的代码如下:
#include <iostream> #include <thread> using namespace std::chrono_literals; int main() { auto task = []() { std::this_thread::sleep_for(3s); std::cout << "Job thread done" << std::endl; }; std::thread t(task); // 执行主线程自己的逻辑,不需要detach std::this_thread::sleep_for(1s); std::cout << "Main thread done" << std::endl; // 自定义逻辑执行完,再等待工作线程结束 t.join(); std::cout << "Everything done" << std::endl; return 0; }
额外注意
detach()仅适用于你完全不需要关心线程生命周期、不需要获取线程执行结果,且能接受线程随主进程退出被强制终止的场景。只要你有等待线程退出、回收线程资源的需求,就不要使用detach()。
内容的提问来源于stack exchange,提问作者RedBox
相关产品推荐
相关产品推荐

