提升未来的延续(然后)死锁

时间:2016-05-06 04:16:48

标签: c++ boost future boost-thread continuations

我目前在Windows上使用Boost 1.55 BOOST_THREAD_VERSION=2BOOST_THREAD_PROVIDES_FUTUREBOOST_THREAD_PROVIDES_FUTURE_CONTINUATION

在单元测试中,延续似乎表现得很好,但在实际代码中它会死锁。

基本代码结构在生产者方面看起来像这样:

typedef std::map<std::string, std::string> Dictionary;

struct Operation
{
    std::unique_ptr<boost::promise<Dictionary>> m_promise;

    boost::future<Dictionary> Start(const Dictionary& data)
    {
        m_promise.reset(new boost::promise<Dictionary>());
        // pass off work to something else
        //   it runs asynchronously then calls Complete
        return m_promise->get_future();
    }

    void Complete(const Dictionary& result)
    {
        m_promise->set_value(result);
        m_promise.reset();
    }
};

消费者方面看起来像这样:

m_Operation.Start(data).then([=](boost::future<Dictionary> f)
{
    // ...
    DoSomething(f.get());
});
return true;

继续被调用,但f.get()无限制地阻塞,set_value也是如此。

据我所知,一个帖子在promise::set_value内被阻止(特别是future_async_shared_state_base::join()),另一个被future::get()阻止(特别是shared_state_base::wait()中的互斥})。

(看起来set_value()中的线程试图在获取get()被阻止的相同互斥锁后破坏延续。)

这是在Boost的更高版本中修复的错误,我使用的是不受支持的配置,还是我在做其他错误?

我不希望因任何原因阻止任何事情发生。它应该只是一个简单的回调&amp;越区切换。

此外,我很困惑为什么延续在一个单独的线程上执行,而不是在set_value内执行。没有一个可能的启动策略似乎支持同步运行延续,我认为这将是自然默认(这就是.NET Tasks的行为)。我真的更喜欢不启动新线程来运行延续,因为这最终只会将工作发布到Asio服务。

或者期货只是这种事情的错误模型?我试过制作一个Asio异步方法,但很快就迷失在样板中。

0 个答案:

没有答案