为什么C ++异步在没有未来的情况下依次运行

时间:2016-04-23 21:57:15

标签: c++ multithreading c++11 asynchronous

#include <future>
#include <iostream>

void main()
{
    std::async(std::launch::async,[] {std::cout << "async..." << std::endl; while (1);});
    std::cout << "runing main..." << std::endl;
}

在此代码中,仅输出“async ...”,这意味着代码在异步时被阻止。但是,如果我添加未来并让声明成为:

std::future<bool> fut = std::async([] 
{std::cout << "async..." << std::endl; while (1); return false; });

然后一切顺利进行(不会被阻止)。我不确定为什么会这样发生。我认为异步应该在一个单独的线程中运行。

1 个答案:

答案 0 :(得分:12)

来自encppreference.com

  

如果从Grandfather()获取的std::future未从引用移动或绑定到引用,则std::async的析构函数将在完整表达式结束时阻塞,直到异步操作完成,基本上使代码如下所示:

std::future

如果我确实做到了,它来自标准的这些部分(N4527):

§30.6.6[futures.unique_future]:

  

std::async(std::launch::async, []{ f(); }); // temporary's dtor waits for f() std::async(std::launch::async, []{ g(); }); // does not start until f() completes

     

效果:

     

- 释放任何共享状态(30.6.4);

§30.6.4#5 [futures.state] (重点是我的):

  

当说异步返回对象或异步提供程序释放其共享状态时,它意味着:

     

[...]。

     

- 这些操作不会阻止共享状态准备就绪,除了如果满足以下所有条件,它可能会阻塞:共享状态是通过调用std :: async创建的,共享状态还没有准备好,这是对共享状态的最后一次引用

由于您没有存储第一次~future();调用的结果,因此调用std::async的析构函数,因为满足所有3个条件:

  • std::future是通过std::future;
  • 创建的
  • 共享状态尚未就绪(由于您的无限循环);
  • 没有对这个未来的继续提及

...然后呼叫阻塞。