> 技术文档 > c++ thread基本用法

c++ thread基本用法

目录

thread基本用法

1. 创建线程

2. 用 Lambda 创建线程

模板:

没有捕获任何变量

Lambda 捕获外部变量

引用捕获外部变量

捕获方式总结:

Lambda 传参数 + 捕获

循环中创建多个线程(捕获变量陷阱)

常用操作

1. join()

2. detach()

3. 向线程传参

4. 获取线程 ID

多个线程实例

线程的生命周期

线程安全问题

常见错误总结


thread基本用法

1. 创建线程

你需要传一个“可调用对象”(函数、Lambda、函数对象等):

#include #include void sherry() { std::cout << \"Hello sherry!\" << std::endl;}int main() { std::thread t(sherry); // 创建并启动线程 t.join();  // 等待线程执行完 return 0;}

2. 用 Lambda 创建线程

模板:

std::thread t([&](/* 参数 */){ // 线程执行逻辑}, /* 参数值 */);t.join(); // 或 t.detach();

没有捕获任何变量

std::thread t([] { std::cout << \"Hello lambda sherry!\" << std::endl;});t.join();

Lambda 捕获外部变量

#include #include int main() { int x = 42; std::thread t([x] { std::cout << \"Captured x = \" << x << std::endl; }); t.join();}
  • [x] 表示按值捕获变量 x(副本);

  • 修改 x 不影响原来的外部变量。

引用捕获外部变量

#include #include int main() { int count = 0; std::thread t([&count] { count = 100; // 修改外部变量 }); t.join(); std::cout << \"count = \" << count << std::endl; // 输出 100}
捕获方式总结:
捕获方式 意义 [] 不捕获任何变量 [x] 按值捕获变量 x [&x] 按引用捕获变量 x [=] 按值捕获所有用到的变量 [&] 按引用捕获所有用到的变量

Lambda 传参数 + 捕获

#include #include int main() { int factor = 2; std::thread t([factor](int a, int b) { std::cout << \"Sum * factor = \" << (a + b) * factor << std::endl; }, 3, 5); // 参数 3 和 5 传给 Lambda t.join();}

线程参数是给 Lambda 的“函数参数”,与捕获无关。

循环中创建多个线程(捕获变量陷阱)

#include #include #include int main() { std::vector threads; for (int i = 0; i < 3; ++i) { threads.emplace_back([i] { std::cout << \"Thread \" << i << std::endl; }); } for (auto& t : threads) t.join();}

常用操作

1. join()

让主线程等待子线程执行完:

t.join(); // 阻塞主线程直到 t 结束

如果不写 join()detach(),主线程结束前会报错或 terminate。


2. detach()

让线程独立运行,主线程不用等它,像“后台线程”:

t.detach(); // 主线程结束,t 可能还在执行

一旦 detach,就无法再控制这个线程了,慎用!


3. 向线程传参

void printMsg(std::string msg) { std::cout << msg << std::endl;}std::thread t(printMsg, \"Hello sherry!\");t.join();

注意:会自动 值传递,如果你传引用,要加 std::ref()


4. 获取线程 ID

std::thread t([] { std::cout << \"My ID is \" << std::this_thread::get_id() << std::endl;});t.join();

多个线程实例

void sherry(int id) { std::cout << \"sherry \" << id << \" started.\" << std::endl;}int main() { std::thread t1(work, 1); std::thread t2(work, 2); t1.join(); t2.join();}

线程的生命周期

  1. 创建(构造时自动启动)

  2. 执行任务

  3. 结束(自动或完成函数)

  4. join 或 detach,销毁资源

若在线程结束前未调用 joindetach,程序会崩溃。


线程安全问题

如果多个线程访问/修改同一数据,就需要加锁(std::mutex

std::mutex mtx;void safePrint(int x) { std::lock_guard lock(mtx); // 自动加锁解锁 std::cout << \"Value: \" << x << std::endl;}

常见错误总结

问题 原因 terminate called without active thread 没有 join()detach() 编译不过 没加 #include 传引用失败 忘了用 std::ref() 数据错乱 多线程访问共享资源没加锁