版权声明:所有的博客都是博主的个人笔记。。。。。 https://blog.csdn.net/qq_35976351/article/details/84186042
Providers
std::promise
和std::future
配合使用,给std::future
传递期望值,下面是最简单的一个用法:
#include <iostream>
#include <functional>
#include <thread>
#include <future>
// 一定要注意是传递引用
void print_int(std::future<int>& fut) {
auto x = fut.get(); // 如果future中没有值,那么在这里一直等待
std::cout << "value: " << x << std::endl;
}
int main() {
std::promise<int> prom;
std::future<int> fut = prom.get_future(); // 获取承诺的future
std::thread th1(print_int, std::ref(fut));
std::cout << "Please input a value:";
int n;
std::cin >> n;
prom.set_value(n); // 把数据传递给承诺的future中
th1.join();
return 0;
}
packaged_task
这是一个更高级的封装,封装的元素是可调用对象,对比上面的promise
,那个是仅仅封装数值的。
构造方式:
template <class T> packaged_task; // undefined
template <class Ret, class... Args> class packaged_task<Ret(Args...)>;
实例说明:
#include <iostream>
#include <future>
#include <chrono>
#include <thread>
int countdown(int from, int to) {
for(int i = from; i != to; --i) {
std::cout << i << std::endl;
// 线程休眠1秒
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout << "Lift off\n";
return from - to;
}
int main() {
std::packaged_task<int(int, int)>tsk(countdown);
std::future<int>ret = tsk.get_future();
// 构造线程开始执行任务,注意是移动构造
std::thread th(std::move(tsk), 10, 0);
// 没有返回结果时,当前线程就一直阻塞
int value = ret.get();
std::cout << "The countdown lasted for " << value << " seconds\n";
th.join();
return 0;
}
Futures
两者只支持移动赋值,无法进行复制操作。
std::future
期望,用于同步数据或者是等待其他线程的异步通信结果。
template <class T> future;
template <class R&> future<R&>; // specialization : T is a reference type (R&)
template <> future<void>; // specialization : T is void
成员函数:
T get();
R& future<R&>::get(); // when T is a reference type (R&)
void future<void>::get(); // when T is void
具体实例参照上面。在不调用wait
类函数的情况下,如果还没计算完成,就一直等待到计算完成。
void wait() const;
等待计算结果完毕,调用完成该函数后,再次调用get()
函数,仅仅是返回一个状态,例如:
// future::wait
#include <iostream> // std::cout
#include <future> // std::async, std::future
#include <chrono> // std::chrono::milliseconds
// a non-optimized way of checking for prime numbers:
bool is_prime (int x) {
for (int i = 2; i < x; ++i)
if (x % i == 0)
return false;
return true;
}
int main () {
// call function asynchronously:
std::future<bool> fut = std::async (is_prime, 194232491);
std::cout << "checking...\n";
fut.wait();
std::cout << "\n194232491 ";
if (fut.get()) // guaranteed to be ready (and not block) after wait returns
std::cout << "is prime.\n";
else
std::cout << "is not prime.\n";
return 0;
}
template <class Rep, class Period>
future_status wait_for (const chrono::duration<Rep,Period>& rel_time) const;
等待计算完毕或者到达指定时间,之后程序继续执行,rel_time
是指的时间间隔。
template <class Clock, class Duration>
future_status wait_until (const chrono::time_point<Clock,Duration>& abs_time) const;
类似于wait_for
,不过abs_time
是指的绝对时间点
扫描二维码关注公众号,回复:
4119295 查看本文章
std::shared_future
包含了std::future
的所有功能,但是可以进行复制操作。
Functions
async
一个异步调用,不等待计算结果,立刻返回一个std::future
类型。计算的结果由返回的std::future
的get()
成员获取。
构造函数:
template <class Fn, class... Args>
future<typename result_of<Fn(Args...)>::type>
async (Fn&& fn, Args&&... args);
template <class Fn, class... Args>
future<typename result_of<Fn(Args...)>::type>
async (launch policy, Fn&& fn, Args&&... args);
一般只使用第一个,第二个的策略具体查询手册即可。
代码实例:
#include <iostream>
#include <future>
bool is_prime(int x) {
std::cout << "Calculating. Please, wait...\n";
for(int i = 2; i < x; ++i) {
if(x % i == 0)
return false;
}
return true;
}
int main() {
std::future<bool>fut = std::async(is_prime, 313222313);
std::cout << "Checking whether 313222313 is prime.\n";
bool ret = fut.get(); // 获取结果,在计算出结果之前,这个会一直阻塞
if(ret) {
std::cout << "It is prime !\n";
} else {
std::cout << "It is not prime !\n";
}
return 0;
}