C++线程detach异常:调用detach后long_process未执行完成求助
线程detach后无法输出"long process end"日志的原因
测试环境
- 系统:Ubuntu 18.05
- 编译器:g++ 7.5
初始测试代码
#include <thread> #include <fstream> #include <chrono> #include <iostream> using namespace std; void long_process() { ofstream ofs("test.log", ios::app); ofs<<"long process start" <<endl; std::this_thread::sleep_for(std::chrono::milliseconds(3*1000)); // 等待3秒 ofs<<"long process end" <<endl; } int main() { ofstream ofs("test.log", ios::app); ofs << "main start" <<endl; std::thread th(long_process); th.detach(); ofs << "main end" <<endl; }
实际日志输出
main start
main end
long process start
预期日志输出
main start
main end
long process start
long process end
join模式下的正常表现
将th.detach()改为th.join()后,日志输出符合预期:
main start
long process start
long process end
main end
尝试的改进代码(问题仍存在)
void long_process() { thread_local ofstream *ofs = new ofstream("test.log", ios::app); *ofs<<"long process start" <<endl; std::this_thread::sleep_for(std::chrono::milliseconds(3*1000)); *ofs<<"long process end" <<endl; } int main() { thread_local ofstream ofs("test.log", ios::app); ofs << "main start" <<endl; std::thread th(long_process); th.detach(); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); ofs << "main end" <<endl; }
原因分析
核心问题是主线程退出会直接终止整个进程,所有已detach的后台线程也会被强制终止。
在初始代码中,主线程执行完输出main end的代码后就直接退出了,此时detach的子线程还处于3秒的sleep阶段,根本没机会执行输出long process end的代码,就被操作系统随进程一起销毁了。
用join()时,主线程会等待子线程完全执行完毕后再退出,所以子线程的所有逻辑都能正常跑完。
你尝试的thread_local和动态分配IO对象的方案,并没有解决主线程提前退出的本质问题——主线程只sleep了1秒就退出,子线程还需要再跑2秒才能输出结束日志,进程终止依旧会打断它的执行。
解决思路
要让detach的子线程完成全部执行,必须保证主线程晚于子线程退出,常见的实现方式有:
- 主线程中设置足够长的等待时间(比如sleep 4秒,确保子线程执行完毕),但这种方式不够灵活;
- 使用
std::condition_variable等同步原语,让子线程执行完毕后主动通知主线程; - 如果子线程是长期运行的后台任务,主线程需要保持运行状态(比如进入无限循环,直到收到退出信号)。
内容的提问来源于stack exchange,提问作者ques
相关产品推荐
相关产品推荐

