C++11 std::async推荐使用 std::launch::async 模式

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强制多线程;

你可能感兴趣的:(Effectivve,Modern,Cpp,c++,java,开发语言)