文章目录
packaged_task
一个 packaged_task 包装了一个可调用对象,并且允许异步获取该可调用对象的结果。
它重载了 operator() ,因此它也是一个可调用对象。
一个 packaged_task 对象包含两个部分:
- stored task:就是一个可调用对象。
- shared state:用于存储 stored task 的执行结果,且可以通过 future 异步访问之。
调用 get_future 成员函数之后,返回的 future 便与 shared state 建立关联。
shared state 会一直存在直到最后一个与之关联的对象释放了该关联,或该对象被销毁。
构造
default (1) | packaged_task() noexcept; |
---|---|
initialization (2) | template <class Fn> explicit packaged_task (Fn&& fn); |
with allocator (3) | template <class Fn, class Alloc> explicit packaged_task (allocator_arg_t aa, const Alloc& alloc, Fn&& fn); |
copy [deleted] (4) | packaged_task (const packaged_task&) = delete; |
move (5) | packaged_task (packaged_task&& x) noexcept; |
如,
std::packaged_task<int(int)> bar ([](int x){return x*2;}); // initialized
赋值
move (1) | packaged_task& operator= (packaged_task&& rhs) noexcept; |
---|---|
copy [deleted] (2) | packaged_task& operator= (const packaged_task&) = delete; |
shared state 相关操作
future<Ret> get_future();
获取和 shared state 关联的 future 。
bool valid() const noexcept;
如果 packaged_task 当前与一个 shared state 关联,则返回 true 。
默认构造的 packaged_task 没有关联的 shared state 。
void reset();
让 packaged_task 与一个新的 shared state 关联。不改变 stored task 。
// packaged_task::get_future
#include <iostream>
#include <utility>
#include <future>
#include <thread>
// a simple task:
int triple (int x) { return x*3; }
int main () {
std::packaged_task<int(int)> tsk (triple); // package task
std::future<int> fut = tsk.get_future(); // get future
std::thread(std::move(tsk),33).detach(); // spawn thread and call task
// ...
int value = fut.get(); // wait for the task to complete and get result
std::cout << "The triple of 33 is " << value << ".\n";
return 0;
}
The triple of 33 is 99.
// packaged_task::reset
#include <iostream>
#include <utility>
#include <future>
#include <thread>
// a simple task:
int triple (int x) { return x*3; }
int main () {
std::packaged_task<int(int)> tsk (triple); // package task
std::future<int> fut = tsk.get_future();
tsk(33);
std::cout << "The triple of 33 is " << fut.get() << ".\n";
// re-use same task object:
tsk.reset();
fut = tsk.get_future();
std::thread(std::move(tsk),99).detach();
std::cout << "Thre triple of 99 is " << fut.get() << ".\n";
return 0;
}
The triple of 33 is 99.
The triple of 99 is 297.
其他操作
void operator()(Args... args);
使用 args 作为参数调用 stored task 。
void make_ready_at_thread_exit (args... args);
使用 args 作为参数调用 stored task ,但是让 shared state 在线程退出时才就绪,而不是一完成调用就让其就绪。
交换
成员函数 | void swap (packaged_task& x) noexcept; |
---|---|
非成员函数 | template <class Ret, class… Args> void swap (packaged_task<Ret(Args…)>& x, packaged_task<Ret(args…)>& y) noexcept; |
交换两者的 stored task 和 shared state 。
promise
可以往一个 promise 对象中存储一个值,然后通过与其关联的 future 对象来获取该值。
一旦 promise 对象构造完成,它便关联有一个 shared state,其用于存储一个值或一个异常。
调用 get_future 成员函数之后,返回的 future 便与 shared state 建立关联。
shared state 会一直存在直到最后一个与之关联的对象释放了该关联,或该对象被销毁。
构造
default (1) | promise(); |
---|---|
with allocator (2) | template <class Alloc> promise (allocator_arg_t aa, const Alloc& alloc); |
copy [deleted] (3) | promise (const promise&) = delete; |
move (4) | promise (promise&& x) noexcept; |
如,
std::promise<int> foo;
std::promise<int> bar = std::promise<int>(std::allocator_arg,std::allocator<int>());
赋值
move (1) | promise& operator= (promise&& rhs) noexcept; |
---|---|
copy [deleted] (2) | promise& operator= (const promise&) = delete; |
shared state 相关操作
设置值
generic template (1) | void set_value (const T& val); void set_value (T&& val); |
---|---|
specializations (2) | void promise<R&>::set_value (R& val); // when T is a reference type (R&) void promise<void>::set_value (void); // when T is void |
generic template (1) | void set_value_at_thread_exit (const T& val); <br.> void set_value_at_thread_exit (T&& val); |
---|---|
specializations (2) | void promise<R&>::set_value_at_thread_exit (R& val); // when T is a reference type (R&) void promise<void>::set_value_at_thread_exit (void); // when T is void |
在线程退出时才让 shared state 就绪。
设置异常
void set_exception (exception_ptr p);
调用 future::get() 函数之后,将抛出 p 指向的异常。
void set_exception_at_thread_exit (exception_ptr p);
在线程退出时才让 shared state 就绪。
获取关联的 future
future<T> get_future();
// promise example
#include <iostream>
#include <functional>
#include <thread>
#include <future>
void print_int (std::future<int>& fut) {
int x = fut.get();
std::cout << "value: " << x << '\n';
}
int main () {
std::promise<int> prom; // create promise
std::future<int> fut = prom.get_future(); // engagement with future
std::thread th1 (print_int, std::ref(fut)); // send future to new thread
prom.set_value (10); // fulfill promise
// (synchronizes with getting the future)
th1.join();
return 0;
}
value: 10
// promise::set_exception
#include <iostream>
#include <functional>
#include <thread>
#include <future>
#include <exception>
void get_int (std::promise<int>& prom) {
int x;
std::cout << "Please, enter an integer value: ";
std::cin.exceptions (std::ios::failbit); // throw on failbit
try {
std::cin >> x; // sets failbit if input is not int
prom.set_value(x);
}
catch (std::exception&) {
prom.set_exception(std::current_exception());
}
}
void print_int (std::future<int>& fut) {
try {
int x = fut.get();
std::cout << "value: " << x << '\n';
}
catch (std::exception& e) {
std::cout << "[exception caught: " << e.what() << "]\n";
}
}
int main () {
std::promise<int> prom;
std::future<int> fut = prom.get_future();
std::thread th1 (print_int, std::ref(fut));
std::thread th2 (get_int, std::ref(prom));
th1.join();
th2.join();
return 0;
}
Please enter an integer value: boogey!
[exception caught: ios_base::failbit caught]
其他操作
交换
成员函数 | void swap (promise& x) noexcept; |
---|---|
非成员函数 | template <class T> void swap (promise<T>& x, promise<T>& y) noexcept; |
交换两者的 shared state 。
async
用于异步调用一个可调用对象。
unspecified policy (1) | template <class Fn, class... Args> future<typename result_of<Fn(Args...)>::type> async (Fn&& fn, Args&&... args); |
---|---|
specific policy (2) | template <class Fn, class... Args> future<typename result_of<Fn(Args...)>::type> async (launch policy, Fn&& fn, Args&&... args); |
在某个时间点调用 fn(args) 。
立即返回,不阻塞。
fn 的返回值通过 async 返回的 future 获取。
形式(1)等同于使用 launch::async|launch::deferred
作为 launce policy 。
policy 可取值如下:
policy | description |
---|---|
launch::async | Asynchronous: Launches a new thread to call fn (as if a thread object is constructed with fn and args as arguments, and accessing the shared state of the returned future joins it). |
launch::deferred | Deferred: The call to fn is deferred until the shared state of the returned future is accessed (with wait or get). At that point, fn is called and the function is no longer considered deferred. When this call returns, the shared state of the returned future is made ready. |
launch::async|launch::deferred |
Automatic: The function chooses the policy automatically (at some point). This depends on the system and library implementation, which generally optimizes for the current availability of concurrency in the system. |
// async example
#include <iostream>
#include <future>
// a non-optimized way of checking for prime numbers:
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 () {
// call is_prime(313222313) asynchronously:
std::future<bool> fut = std::async (is_prime,313222313);
std::cout << "Checking whether 313222313 is prime.\n";
// ...
bool ret = fut.get(); // waits for is_prime to return
if (ret) std::cout << "It is prime!\n";
else std::cout << "It is not prime.\n";
return 0;
}
Checking whether 313222313 is prime.
Calculating. Please, wait...
It is prime!
future
用于访问一个 provider 对象中的值。
构造
default (1) | future() noexcept; |
---|---|
copy [deleted] (2) | future (const future&) = delete; |
move (3) | future (future&& x) noexcept; |
赋值
move (1) | future& operator= (future&& rhs) noexcept; |
---|---|
copy [deleted] (2) | future& operator= (const future&) = delete; |
获取值
检查 future 是否有效
bool valid() const noexcept;
如果 future 和 shared state 关联,则返回 true 。默认构造的 future 没有关联的 shared state 。
get
generic template (1) | T get(); |
---|---|
reference specialization (2) | R& future<R&>::get(); // when T is a reference type (R&) |
void specialization (3) | void future<void>::get(); // when T is void |
当 shared state 就绪时,获取 shared state 中的值/异常。
如果 shared state 还未就绪,则阻塞。
等待 shared state 就绪
void wait() const;
如果 shared state 还未就绪,则阻塞。
template <class Rep, class Period>
future_status wait_for (const chrono::duration<Rep,Period>& rel_time) const;
和 wait 类似,但是最多等待 rel_time 时长。
如果 shared state 包含一个 deferred 函数,则立即返回,不阻塞。
返回值如下:
value | description |
---|---|
future_status::ready | The shared state is ready: the producer has set a value or exception. |
future_status::timeout | The function waited for rel_time without the shared state becoming ready. |
future_status::deferred | The shared state contains a deferred function. |
template <class Clock, class Duration>
future_status wait_until (const chrono::time_point<Clock,Duration>& abs_time) const;
和 wait_for 类似,只是以绝对时间指定超时时间。
// future::wait
#include <iostream>
#include <future>
#include <chrono>
// 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;
}
checking...
194232491 is prime.
// future::wait_for
#include <iostream>
#include <future>
#include <chrono>
// 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,700020007);
// do something while waiting for function to set future:
std::cout << "checking, please wait";
std::chrono::milliseconds span (100);
while (fut.wait_for(span)==std::future_status::timeout)
std::cout << '.';
bool x = fut.get();
std::cout << "\n700020007 " << (x?"is":"is not") << " prime.\n";
return 0;
}
其他操作
shared_future<T> share();
返回一个 shared_future,该返回值会获取当前 future 的 shared state 。即,此函数过后,future 没有与 shared state 关联。
shared_future
和 future 类似,只是它允许拷贝,允许多个 shared_future 共享一个 shared state ,允许多次访问 shared state 中的值。
shared state 会一直保持有效,直到最后一个与之关联的对象释放该关联或该对象被销毁。
构造
default (1) | shared_future() noexcept; |
---|---|
copy (2) | shared_future (const shared_future& x); |
move (3) | shared_future (shared_future&& x) noexcept; |
move from future (4) | shared_future (future<T>&& x) noexcept; |
赋值
move (1) | shared_future& operator= (shared_future&& rhs) noexcept; |
---|---|
copy (2) | shared_future& operator= (const shared_future& rhs); |
获取值
检查 future 是否有效
bool valid() const noexcept;
如果 shared_future 和 shared state 关联,则返回 true 。默认构造的 shared_future 没有关联的 shared state 。
get
generic template (1) | T get(); |
---|---|
reference specialization (2) | R& shared_future<R&>::get(); // when T is a reference type (R&) |
void specialization (3) | void shared_future<void>::get(); // when T is void |
当 shared state 就绪时,获取 shared state 中的值/异常。
如果 shared state 还未就绪,则阻塞。
等待 shared state 就绪
void wait() const;
如果 shared state 还未就绪,则阻塞。
template <class Rep, class Period>
future_status wait_for (const chrono::duration<Rep,Period>& rel_time) const;
和 wait 类似,但是最多等待 rel_time 时长。
如果 shared state 包含一个 deferred 函数,则立即返回,不阻塞。
返回值如下:
value | description |
---|---|
future_status::ready | The shared state is ready: the producer has set a value or exception. |
future_status::timeout | The function waited for rel_time without the shared state becoming ready. |
future_status::deferred | The shared state contains a deferred function. |
template <class Clock, class Duration>
future_status wait_until (const chrono::time_point<Clock,Duration>& abs_time) const;
和 wait_for 类似,只是以绝对时间指定超时时间。
来源:CSDN
作者:W.T.F.
链接:https://blog.csdn.net/fcku_88/article/details/104186685