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();}
线程的生命周期
-
创建(构造时自动启动)
-
执行任务
-
结束(自动或完成函数)
-
join 或 detach,销毁资源
若在线程结束前未调用 join
或 detach
,程序会崩溃。
线程安全问题
如果多个线程访问/修改同一数据,就需要加锁(std::mutex
)
std::mutex mtx;void safePrint(int x) { std::lock_guard lock(mtx); // 自动加锁解锁 std::cout << \"Value: \" << x << std::endl;}
常见错误总结
join()
或 detach()
#include
std::ref()