【问题标题】:boost::future::then() not returning future that blocks on destructionboost::future::then() 不返回阻止销毁的未来
【发布时间】:2018-02-07 18:41:35
【问题描述】:

我编写了这个示例代码来测试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。 执行应该在函数bar() 中的f.then() 处被阻止,因为boost::future&lt;void&gt; 类型的临时变量应该在销毁时被阻止,并且输出应该是

3405691582
Should have blocked?

但在我的应用程序中,对f.then() 的调用会阻止执行,直到不调用继续。 这里发生了什么?

【问题讨论】:

  • 我是古玩 - 增强使用是必须的吗?我能够仅使用标准功能 gist.github.com/artemyv/baab7c8c74bb7fde07ebdcf2aee19881 来做同样的事情
  • @ArtemyVysotsky 不,在这里实现相同的功能是没有问题的。这个问题几乎不是出于好奇。此外,就可组合性而言,使用 .then 似乎比使用 if-else 更好。您会意识到在 std::async 创建的期货的情况下会发生相同的行为,它们会在销毁时阻塞,这应该在这里发生,并且它也发生在我的应用程序代码中。我的问题是为什么在这种情况下没有发生。或者它是否也可以被其他人复制。谢谢您的意见。

标签: c++ multithreading boost boost-thread


【解决方案1】:

请注意,future 会阻塞在析构函数中的唯一一次记录是当您使用std::asynclaunch::async 的启动策略时。

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

答案列出了围绕该主题进行的许多讨论。提案N3776 进入了C++14:

本文提供了实施积极的 SG1 稻草民意调查的建议措辞,以澄清 ~future~shared_future 除非可能存在异步,否则不要阻塞。

cppreference.com 文档std::async

您的代码从未使用过异步,因此如果将来派生的任何在销毁时阻塞,那将是令人惊讶的。

更通用 盟友,很明显,共识是阻止破坏是一个不幸的设计缺陷,而不是您期望在较新的扩展(例如 .then 延续)中引入的东西。

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

  • 返回的future 的行为与从boost::async 返回的future 相同,从then 返回的future 对象的析构函数将阻塞。这可能会在未来的版本中发生变化。

应该被删除。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多