async
真假多线程std::launch::async
真多线程std::launch::async | std::launch::deferred
可能多线程std::launch::deferred
假多线程enum class launch
{
async = 1, // 0b1
deferred = 2, // 0b10
any = async | deferred // 0b11
};
std::launch::async
: 一定在另一个线程跑函数std::launch::deferred
: get,wait
代码所在线程跑函数;即调用get,wait
的时候再串行执行函数; 如果不调用则不执行;
any
即默认可能延迟, 也可能立即执行; 跟系统当时的负载均衡, 超限等方面的阈值决定, 采取延迟还是立即执行;
std::launch::any
void t() {
auto fut = std::async(f); // run f using default launch policy
}
f, t
可能在一个线程执行, 也可能在不同的线程执行;fut.get|fut.wait, f
这两个也可能在一个线程, 也可能不在一个线程;f
可能在执行, 可能不在执行;TLS:thread local storage
thread_local
修饰的可能会新创建, 也可能不创建; 就有很大的问题;
wait
问题auto fut = std::async(f);
while (fut.wait_for(100ms) != std::future_status::ready) {
}
enum class future_status {
ready,
timeout,
deferred
};
f
可能永远也没有执行; fut
的状态永远是deferred
; 永远循环下去;
这种可能漏洞可能永远也不会触发, 因为即使是压测或其他测试, 测试环境可能永远也不会出现; 但是在一些极端环境就啃根出现;
wait_for(0)
状态查询;
auto fut = std::async(f);
if (fut.wait_for(0) != std::future_status::deferred) {
// do something and return;
// ...use wait or get on fut to call f synchronously
} else {
while (fut.wait_for(100ms) != std::future_status::deferred) {
// task is neither deferred nor ready, so do concurrent work until it's ready
}
// now is ready.
}
default
使用条件f
不用和get,wait
调用者所在线程并行;thread_local
变量的线程安全;get,wait
时阻塞执行; 接受不调用get, wait
不执行;std::launch::async
auto fut = std::async(std::launch::async, f);
std::launch::async
: c++11
template<typename F, typename... Ts>
inline
std::future<typename std::result_of<F(Ts...)>::type>
reallyAsync(F&& f, Ts&&... params) // return future
{
// for asynchronous // call to f(params...)
return std::async(std::launch::async,
std::forward<F>(f), std::forward<Ts> (params)...);
}
std::launch::async
: c++14
template<typename F, typename... Ts>
inline
auto
reallyAsync(F&& f, Ts&&... params) // return future
{
// for asynchronous // call to f(params...)
return std::async(std::launch::async,
std::forward<F>(f), std::forward<Ts> (params)...);
}
c++11
不支持返回值类型推理;deferred + async
的结合, 行为未知, 大多数异步;thread_local
, 任务不执行, wait
无限等待;std::launch::async
强制多线程;