boost :: future :: then()不会在将来阻止破坏时阻止

时间:2017-08-30 06:52:28

标签: c++ multithreading boost boost-thread

我编写了这个示例代码来测试boost::future在我的应用程序中使用的延续。

#include <iostream>
#include <functional>
#include <unistd.h>
#include <exception>

#define BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION

#include <boost/thread/future.hpp>

void magicNumber(std::shared_ptr<boost::promise<long>> p)
{
    sleep(5);
    p->set_value(0xcafebabe);
}

boost::future<long> foo()
{
    std::shared_ptr<boost::promise<long>> p = 
    std::make_shared<boost::promise<long>>();

    boost::future<long> f = p->get_future();

    boost::thread t([p](){magicNumber(p);});

    t.detach();

    return f;
}

void bar()
{
    auto f = foo();
    f.then([](boost::future<long> f) { std::cout << f.get() << std::endl; });
    std::cout << "Should have blocked?" << std::endl; 
}

int main()
{   
    bar();

    sleep (6);

    return 0;
}

在使用boost版本1.64.0_1进行编译,链接和运行时,我得到以下输出:

Should have blocked?
3405691582

但根据boost::future::then的文档here。 应该在函数f.then()的{​​{1}}处阻止执行,因为类型bar()的临时变量应该在销毁时阻塞,输出应该

boost::future<void>

在我的应用程序中,对3405691582 Should have blocked? 的调用阻止执行,直到不调用continuation。 这里发生了什么?

1 个答案:

答案 0 :(得分:1)

请注意,在std::async启动策略为launch::async的情况下使用~future时,唯一一次将在析构函数中阻止的时间用于记录。

请参阅Why is the destructor of a future returned from `std::async` blocking?

答案列出了围绕这一主题进行的许多讨论。提案N3776使其成为C ++ 14:

  

本文提供了实施积极的SG1草案调查的建议措辞,以澄清~shared_future和   .then除非存在异步,否则不会阻止。

cppreference.com文件std::async

enter image description here

您的代码从未使用异步,因此如果将来派生的阻止销毁,那将会令人惊讶。

更一般 很明显,很明显,共识是阻止破坏是一个不幸的设计瑕疵,而不是你期望在更新的扩展上引入的东西(例如key延续)。

我只能假设这是一个文档错误的情况,其中的措辞

  
      
  • 返回的期货表现为从boost :: async返回的期货,从那时返回的未来对象的析构函数将被阻止。这可能会在未来的版本中发生变化。
  •   

应该删除。