当未存储返回值时,std :: async不会生成新线程

时间:2012-02-28 21:59:07

标签: c++ multithreading asynchronous

考虑一下我有lamba foo只做一些东西,不需要返回任何东西。 当我这样做时:

std::future<T> handle = std::async(std::launch::async, foo, arg1, arg2);

一切运行良好,lamba将在新线程中生成。 但是,当我不存储std::future返回的std::async时,foo将在主线程中运行并阻止它。

std::async(std::launch::async, foo, arg1, arg2);

我在这里缺少什么?

3 个答案:

答案 0 :(得分:17)

来自just::thread documentation

  

如果策略为std::launch::async,则在其自己的线程上运行INVOKE(fff,xyz...)。当此线程完成时,返回的std::future将变为就绪状态,并将保留函数调用抛出的返回值或异常。与返回的std::future的异步状态关联的最后一个对象的析构函数将阻塞,直到将来准备就绪。

std::async(std::launch::async, foo, arg1, arg2);

返回的未来未在任何地方分配,其析构函数会阻塞,直到foo完成。

答案 1 :(得分:4)

我想在async and ~future上添加一篇关于Herb Sutter撰写的文章的链接,其中他认为期货永远不会阻止。

答案 2 :(得分:0)

为什么要阻止?

  
      
  1. std::async();返回std::future 临时对象
  2.   立即销毁
  3. 临时对象,并调用desctructor。
  4.   
  5. std::future析构函数正在阻塞。这很糟糕也很麻烦。
  6.   

为什么分配是好的?

  

通过分配给变量,返回的对象不会立即被销毁,但是会在以后直到销毁代码范围的末尾。

代码示例:main1没问题。 main2main3等效地阻止了主线程。

void forever() {
    while (true);
}

void main1() {
    std::future<void> p = std::async(std::launch::async, forever);
    std::cout << "printing" << std::endl; // can print, then forever blocking
}

void main2() {
    std::async(std::launch::async, forever);
    std::cout << "printing" << std::endl; // forever blocking first, cannot print
}

void main3() {
    {std::future<void> p = std::async(std::launch::async, forever);}
    std::cout << "printing" << std::endl; // forever blocking first, cannot print
}

查看cplusplus.com

std :: async的返回值 选择launch :: async时,返回的future将链接到 即使从未访问过共享状态,创建的线程结束: 在这种情况下,它的析构函数与fn的返回同步。 因此,异步不应忽略返回值 行为,即使fn返回无效。