线程生命周期
内容介绍
std::thread 表示一个正在运行或可管理的系统线程。线程启动后,主线程必须决定如何收尾:
join():等待线程执行完。detach():让线程脱离管理,后台自行运行。std::jthread:C++20,析构时自动请求停止并等待结束。
基本用法
#include <iostream>
#include <thread>
void worker() {
std::cout << "worker thread\n";
}
int main() {
std::thread t(worker);
t.join();
}joinable
std::thread 对象析构前,如果仍然 joinable(),程序会调用 std::terminate()。
std::thread t([] {
// do work
});
if (t.joinable()) {
t.join();
}detach 谨慎使用
std::thread([] {
// background work
}).detach();detach 后无法等待线程结束,也很难管理异常、资源和退出时机。工程中更推荐线程池、任务队列或 std::jthread。
jthread
#include <iostream>
#include <thread>
int main() {
std::jthread t([] {
std::cout << "auto join\n";
});
}std::jthread 析构时会自动 join,比裸 std::thread 更不容易忘记收尾。
最佳代码实践
- 普通后台任务优先考虑
std::jthread。 - 使用
std::thread时,确保所有路径都会join或detach。 - 不要让线程访问已经销毁的局部变量。
- 线程对象可以移动,不能复制。
常见错误用法
void start() {
int value = 42;
std::thread([&] {
std::cout << value << '\n';
}).detach();
}问题:start 返回后 value 已销毁,分离线程继续访问会产生未定义行为。
注意事项
join是等待,不是终止线程。- C++ 标准库没有强制杀死线程的安全 API。
- 想让线程退出,应该设计停止标志、关闭队列或使用 cpp协作取消。
学习路径
- 上一节:cpp并发性能模型
- 当前阶段:cpp多线程
- 下一节:cpp线程传参与返回值