C++ 异步操作
std::future
是 C++11 中的标准库类,用于异步任务的管理和获取结果。它允许你在一个线程中启动一个异步任务,然后在另一个线程中等待任务完成并获取其结果。
以下是使用 std::future
的常见用法:
- 启动异步任务:
std::future<int> result = std::async([]() {
// 执行一些异步操作并返回一个结果
return 42;
});
等待任务完成:
result.wait(); // 阻塞等待任务完成
获取任务结果:
int value = result.get(); // 获取任务的返回值
注意:在调用 get
之前,确保任务已经完成,否则它会阻塞等待任务完成。
检查任务是否完成:
if (result.valid()) {
// 任务已完成
} else {
// 任务未完成
}
设置超时等待:
std::future_status status = result.wait_for(std::chrono::seconds(2));
if (status == std::future_status::ready) {
// 任务已完成
int value = result.get();
} else if (status == std::future_status::timeout) {
// 任务尚未完成,等待超时
} else if (status == std::future_status::deferred) {
// 任务还未开始执行
}
共享状态:
std::future
可以用于获取异步任务的结果,但一旦获取后,它不能再次用于其他操作。如果需要多次获取结果,可以使用 std::shared_future
。
示例:
/*****************************
std::async
******************************/
#include <iostream>
#include <functional>
#include <future>
#include <thread>
using namespace std;
int func(int num) { return num + 1; }
int main() {
// auto : std::future<int>
auto result = std::async(func, 5);
// 阻塞等待任务完成
result.wait();
cout << result.get() << endl;
return 0;
}
async
是比 future
,packaged_task
,promise
更高级的东西,它是基于任务的异步操作,通过 async 可以直接创建异步的任务,返回的结果会保存在 future
中,不需要像 packaged_task
和 promise
那么麻烦
c++11 关于异步操作提供了 future 相关的类,
std::future
std::promise
std::packaged_task
std::future
比 std::thread
高级些,std::future
作为异步结果的传输通道,通过 get()
可以很方便的获取线程函数的返回值,std::promise
用来包装一个值,将数据和 future
绑定起来,而 std::packaged_task 则用来包装一个调用对象,将函数和 future
绑定起来,方便异步调用。而std::future
是不可以复制的,如果需要复制放到容器中可以使用 std::shared_future
。
三者之间的关系
std::future 用于访问异步操作的结果,而 std::promise
和 std::packaged_task
在 future 高一层,它们内部都有一个 future,promise包装的是一个值,packaged_task
包装的是一个函数,当需要获取线程中的某个值,可以使用 std::promise
,当需要获取线程函数返回值,可以使用 std::packaged_task
。
/*****************************
std::promise 与 std::future 配合使用
******************************/
#include <iostream>
#include <future>
#include <functional>
#include <thread>
using namespace std;
void func(std::future<int>& fut) {
int x = fut.get();
cout << "value: " << x << endl;
}
int main() {
// 创建一个 std::promise 对象,它可以用来设置异步任务的结果,这里结果的类型是 int
std::promise<int> prom;
// 通过 prom.get_future() 获取与 prom 共享状态的 std::future 对象
std::future<int> fut = prom.get_future();
// 创建一个新线程 t,并将 fut 传递给线程执行的函数 func
std::thread t(func, std::ref(fut));
// 在主线程中使用 prom.set_value(144) 设置异步任务的结果为 144
prom.set_value(144);
// 等待线程结束
t.join();
return 0;
}
/*****************************
std::packaged_task 与 std::future 配合使用
******************************/
#include <iostream>
#include <functional>
#include <future>
#include <thread>
using namespace std;
int func(int num) {
return num + 1;
}
int main() {
// 创建 packaged_task 对象,包装了函数 func
std::packaged_task<int(int)> task(func);
// 通过从task获取相关的future 创建std::future对象 fut
std::future<int> fut = task.get_future();
// 创建新线程,并将 task移动到线程中
std::thread t(std::move(task), 5);
// 等待线程退出
t.join();
cout << "result " << fut.get() << endl;
return 0;
}