Lambda 表达式作为 std::thread 参数
-
- [1. 基本使用方法](#1. 基本使用方法)
-
- [1.1 最简单的 Lambda 线程](#1.1 最简单的 Lambda 线程)
- [1.2 带参数的 Lambda](#1.2 带参数的 Lambda)
- [2. 捕获列表详解](#2. 捕获列表详解)
-
- [2.1 不同的捕获方式](#2.1 不同的捕获方式)
- [3. 应用示例](#3. 应用示例)
-
- [3.1 带返回值的 Lambda 线程](#3.1 带返回值的 Lambda 线程)
- [4. 注意事项和陷阱](#4. 注意事项和陷阱)
-
- [4.1 生命周期问题](#4.1 生命周期问题)
- [4.2 异常安全](#4.2 异常安全)
1. 基本使用方法
1.1 最简单的 Lambda 线程
cpp
复制代码
#include <iostream>
#include <thread>
int main() {
// 基本 lambda 表达式
std::thread t([]() {
std::cout << "线程正在运行" << std::endl;
});
t.join();
return 0;
}
1.2 带参数的 Lambda
cpp
复制代码
#include <iostream>
#include <thread>
int main() {
int value = 42;
std::thread t([value]() {
std::cout << "捕获的值: " << value << std::endl;
});
t.join();
// 直接传递参数给 lambda
std::thread t2([](int x, const std::string& str) {
std::cout << x << ", " << str << std::endl;
}, 100, "Hello");
t2.join();
return 0;
}
2. 捕获列表详解
2.1 不同的捕获方式
cpp
复制代码
#include <iostream>
#include <thread>
#include <vector>
int main() {
int a = 1, b = 2, c = 3;
// 1. 值捕获 [a, b]
std::thread t1([a, b]() {
std::cout << "值捕获: a=" << a << ", b=" << b << std::endl;
// a = 10; // 错误:const 值,不能修改
});
// 2. 引用捕获 [&a, &b]
std::thread t2([&a, &b]() {
a = 10;
b = 20;
std::cout << "引用捕获: 修改后 a=" << a << ", b=" << b << std::endl;
});
// 3. 混合捕获 [a, &b]
std::thread t3([a, &b]() {
// a 是值,b 是引用
b = a * 2;
std::cout << "混合捕获: a=" << a << ", b=" << b << std::endl;
});
// 4. 默认值捕获 [=]
std::thread t4([=]() {
std::cout << "默认值捕获: a=" << a << ", b=" << b << ", c=" << c << std::endl;
});
// 5. 默认引用捕获 [&]
std::thread t5([&]() {
a = 100;
b = 200;
c = 300;
std::cout << "默认引用捕获: 修改所有变量" << std::endl;
});
// 6. 可变 lambda(允许修改值捕获的变量)
std::thread t6([a]() mutable {
int temp = a; // 可以修改副本
temp = 999;
std::cout << "mutable: 修改副本为 " << temp << std::endl;
});
t1.join(); t2.join(); t3.join();
t4.join(); t5.join(); t6.join();
std::cout << "最终值: a=" << a << ", b=" << b << ", c=" << c << std::endl;
return 0;
}
3. 应用示例
3.1 带返回值的 Lambda 线程
cpp
复制代码
#include <iostream>
#include <thread>
#include <future>
#include <functional>
int main() {
// 方法1:使用 std::async 获取返回值
auto future1 = std::async([](int a, int b) -> int {
std::this_thread::sleep_for(std::chrono::seconds(1));
return a + b;
}, 10, 20);
int result1 = future1.get();
std::cout << "结果1: " << result1 << std::endl;
// 方法2:使用 promise/future
std::promise<int> promise;
std::future<int> future2 = promise.get_future();
std::thread t2([&promise]() {
std::this_thread::sleep_for(std::chrono::seconds(1));
promise.set_value(42);
});
int result2 = future2.get();
std::cout << "结果2: " << result2 << std::endl;
t2.join();
// 方法3:使用 packaged_task
std::packaged_task<int(int, int)> task([](int x, int y) {
return x * y;
});
std::future<int> future3 = task.get_future();
std::thread t3(std::move(task), 6, 7);
int result3 = future3.get();
std::cout << "结果3: " << result3 << std::endl;
t3.join();
return 0;
}
4. 注意事项和陷阱
4.1 生命周期问题
cpp
复制代码
#include <iostream>
#include <thread>
#include <memory>
void dangerous_example() {
std::thread t;
{
int local_var = 42;
// 危险!捕获了局部变量的引用
t = std::thread([&local_var]() {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "local_var = " << local_var << std::endl; // 未定义行为!
});
} // local_var 在这里被销毁
t.join(); // 访问已销毁的变量!
}
void safe_example() {
// 方法1:值捕获
{
int value = 100;
std::thread t1([value]() { // 安全:复制值
std::cout << "值捕获: " << value << std::endl;
});
t1.join();
}
// 方法2:使用智能指针共享所有权
{
auto shared_data = std::make_shared<int>(200);
std::thread t2([shared_data]() { // 安全:共享所有权
std::cout << "智能指针: " << *shared_data << std::endl;
});
t2.join();
}
// 方法3:等待局部作用域结束
{
int local_var = 300;
std::thread t3([&local_var]() {
std::cout << "引用捕获(短时间内): " << local_var << std::endl;
});
t3.join(); // 在 local_var 销毁前 join
}
}
4.2 异常安全
cpp
复制代码
#include <iostream>
#include <thread>
#include <stdexcept>
void exception_example() {
// lambda 中的异常不会传播到主线程
std::thread t([]() {
try {
throw std::runtime_error("线程内部错误");
} catch (const std::exception& e) {
std::cerr << "捕获到异常: " << e.what() << std::endl;
}
});
t.join();
// 未捕获的异常会终止程序
std::thread t2([]() {
throw std::runtime_error("未捕获的异常");
});
t2.join(); // 程序可能在此终止
}
class ExceptionSafeThread {
private:
std::thread worker_;
public:
ExceptionSafeThread() {
worker_ = std::thread([this]() {
try {
this->worker_func();
} catch (const std::exception& e) {
std::cerr << "线程异常: " << e.what() << std::endl;
} catch (...) {
std::cerr << "未知异常" << std::endl;
}
});
}
void worker_func() {
// 工作逻辑
}
~ExceptionSafeThread() {
if (worker_.joinable()) {
worker_.join();
}
}
};