std::packaged_task 可将函数、lambda 等可调用对象包装为异步任务,通过 get_future() 获取 future 以获取返回值或异常;1. 创建 std::packaged_task<int()> 并传入函数 compute;2. 调用 get_future() 获取 future 对象;3. 将 task 移入新线程执行;4. 主线程调用 result.get() 获取结果;支持带参函数,在线程中调用 task(3,7) 传参;可用 lambda 内联复杂逻辑;若任务抛异常,future::get() 会重新抛出,便于统一错误处理。

在C++中,std::packaged_task 是一种将可调用对象(如函数、lambda表达式等)包装成异步任务的机制,它与 std::future 配合使用,可以方便地获取异步任务的返回值。这种机制适用于需要在后台执行任务并后续获取结果的场景。
std::packaged_task 模板参数是函数的签名,例如 int() 表示一个无参、返回 int 的函数。构造时传入具体的可调用对象,之后可以通过 get_future() 获取一个 future 对象,用于将来获取任务的返回值。
示例代码:
#include <iostream>
#include <thread>
#include <future>
int compute() {
return 42;
}
int main() {
std::packaged_task<int()> task(compute);
std::future<int> result = task.get_future();
std::thread t(std::move(task));
t.join();
std::cout << "Result: " << result.get() << std::endl; // 输出 42
return 0;
}
说明:
立即学习“C++免费学习笔记(深入)”;
如果任务函数有参数,可以在调用 task 时传入。注意:task 本身不支持直接绑定参数,需在调用 operator() 时提供。
#include <iostream>
#include <thread>
#include <future>
int add(int a, int b) {
return a + b;
}
int main() {
std::packaged_task<int(int, int)> task(add);
std::future<int> result = task.get_future();
std::thread t([&task]() {
task(3, 7); // 在线程中调用,传入参数
});
t.join();
std::cout << "Add result: " << result.get() << std::endl; // 输出 10
return 0;
}
注意:lambda 捕获 task 时要确保生命周期安全。也可以直接移动 task 到线程中执行,避免捕获问题。
更常见的做法是用 lambda 包装逻辑,便于内联定义复杂操作。
std::packaged_task<double()> task([]() {
double sum = 0.0;
for (int i = 1; i <= 1000000; ++i) {
sum += 1.0 / i;
}
return sum;
});
std::future<double> fut = task.get_future();
std::thread t(std::move(task));
t.join();
double value = fut.get();
std::cout << "Computed sum: " << value << std::endl;
这种方式适合封装局部计算逻辑,无需单独定义函数。
如果任务抛出异常,异常会被捕获并存储,调用 future::get() 时会重新抛出。
std::packaged_task<void()> task([](){
throw std::runtime_error("Something went wrong");
});
std::future<void> fut = task.get_future();
std::thread t(std::move(task));
t.join();
try {
fut.get(); // 这里会抛出异常
} catch (const std::exception& e) {
std::cout << "Exception: " << e.what() << std::endl;
}
这样可以统一在主线程或其他上下文中处理异步任务中的错误。
基本上就这些。std::packaged_task 提供了一种灵活的方式将任意可调用对象转为可异步执行的任务,并通过 future 安全获取返回值或异常。结合线程使用时注意资源管理和生命周期,避免悬挂引用或未 join 的线程。
以上就是c++++如何使用std::packaged_task封装异步任务_c++获取异步任务的返回值的详细内容,更多请关注php中文网其它相关文章!
c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号