线程传参与返回值
内容介绍
线程函数可以接收参数,但参数默认会被复制到线程内部。引用传递、指针传递和返回值都需要特别处理生命周期。
值传递
#include <iostream>
#include <thread>
#include <string>
void print(std::string text) {
std::cout << text << '\n';
}
int main() {
std::thread t(print, "hello");
t.join();
}引用传递
需要用 std::ref 明确告诉 std::thread 传引用。
#include <iostream>
#include <thread>
#include <functional>
void add(int& value) {
value += 1;
}
int main() {
int number = 1;
std::thread t(add, std::ref(number));
t.join();
std::cout << number << '\n';
}lambda 捕获
int value = 10;
std::thread t([value] {
std::cout << value << '\n';
});
t.join();跨线程优先按值捕获。按引用捕获必须保证引用对象在线程结束前仍然活着。
返回值
std::thread 本身不直接返回值。返回值可以使用 cppfuture和promise,或者共享变量配合锁。
最佳代码实践
- 跨线程传参优先值传递。
- 引用传递必须用
std::ref,并保证生命周期。 - 复杂对象优先用
std::shared_ptr表达共享所有权。 - 返回值优先用
std::future,不要手写共享变量加忙等。
常见错误用法
void change(int& x) {
x = 100;
}
int main() {
int value = 0;
std::thread t(change, value); // 错误:这里会尝试复制,不是传引用
t.join();
}正确写法:
std::thread t(change, std::ref(value));注意事项
- 线程参数会先 decay-copy,数组会退化,引用会丢失。
std::ref只解决引用传递,不解决生命周期问题。- 线程异常不会自动传回主线程,主线程需要通过
future或异常捕获机制处理。
学习路径
- 上一节:cpp线程生命周期
- 当前阶段:cpp多线程
- 下一节:cpp互斥锁与RAII