线程生命周期

内容介绍

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 时,确保所有路径都会 joindetach
  • 不要让线程访问已经销毁的局部变量。
  • 线程对象可以移动,不能复制。

常见错误用法

void start() {
    int value = 42;
    std::thread([&] {
        std::cout << value << '\n';
    }).detach();
}

问题:start 返回后 value 已销毁,分离线程继续访问会产生未定义行为。

注意事项

  • join 是等待,不是终止线程。
  • C++ 标准库没有强制杀死线程的安全 API。
  • 想让线程退出,应该设计停止标志、关闭队列或使用 cpp协作取消

学习路径