【问题标题】:boost.future: are these two pieces of code equivalent?boost.future:这两段代码是等价的吗?
【发布时间】:2015-01-23 05:26:29
【问题描述】:

我担心这两段代码可能会导致隐藏的阻塞问题。对我来说,第一个有效,第二个无效。我对非工作代码不会阻塞之类的东西更有信心,但它不能正常工作。

我的问题是:这两段代码是否等效,或者我在工作代码的第一个延续中有 .get() 的事实可以使我的代码在那时阻塞?

工作代码。

auto finished = user2.ReceiveChatMessages().then([&]
(boost::future<std::vector<ServerReply>> && receivedMessages) 
    {
        number_received_messages_in_continuation = receivedMessages.get().size();

        //Will this .get make my code block in any case?
        return user2.ReceiveChatMessages().get();
    })
   .then([&](boost::future<std::vector<ServerReply>> && receivedMessages) {
       number_received_messages_in_continuation += receivedMessages.get().size();
});

无效的代码。

auto finished = user2.ReceiveChatMessages().then([&]
(boost::future<std::vector<ServerReply>> && receivedMessages) 
    {
        number_received_messages_in_continuation = receivedMessages.get().size();

        //No .get() here
        return user2.ReceiveChatMessages();
    }).unwrap() //We need to unwrap
   .then([&](boost::future<std::vector<ServerReply>> && receivedMessages) {
       number_received_messages_in_continuation += receivedMessages.get().size();
});

【问题讨论】:

  • "[...] 我有一个 .get() [...] 可以让我的代码阻塞 [...] 吗?"。除非你能保证未来必须准备好。是的,这是.get() 的记录行为。 (receivedMessages 是一个读取未来的例子,因为只有当它准备好时才会调用延续)
  • 当然,后者也是会发生的。请注意,这些不是互斥的(如果它永远不会准备好,等待它准备好可能会永远阻塞。例如,当出现死锁时(或只是程序员失败:))
  • 我无法弄清楚为什么非工作代码不起作用。对于第一次继续,它甚至没有简单的返回 boost::async([] { return true });。它永远阻塞。为什么?我误解了某些东西,或者这是一个实现错误。
  • “它不起作用”是什么意思?在我看来,它甚至不应该编译。第二个延续应该是一个布尔值:foo().then([&amp;](boost::future&lt;T&gt;&amp;&amp;) {return true;}).then([&amp;](boost::future&lt;bool&gt;&amp;&amp;) {}); ?
  • api_returns_fut().then([](future&lt;...&gt; &amp;&amp; r) { return boost::async([] { return true; }); }).unwrap().then([](future&lt;bool&gt; &amp;&amp; r2) { ...; });。这个例子从不调用第二个延续,为什么?

标签: c++ boost concurrency


【解决方案1】:

由于您似乎在使用延续时遇到了一般问题,让我展示一下我认为通常的模式并现场演示:

Live On Coliru

#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread/future.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>

using boost::async;
using boost::future;

int foo(int i) { return i*2; }

int main() {

    auto consequence = async(boost::bind(foo, 42))
        .then([&](future<int> j) { return j.get()-4; })
        .then([&](future<int> k) { return k.get()/2; })
        .then([&](future<int> l) { return l.get()+2; });

    return consequence.get();
}

42 退出

【讨论】:

【解决方案2】:

这似乎是boost.future 实现中的一个错误,它阻止了非工作代码的工作:

https://svn.boost.org/trac/boost/ticket/10964

代码在功能上是等效的,但工作代码可能会在return user2.ReceiveChatMessages().get() 中阻塞,因此如果在调用它的线程中执行延续,它可能会阻塞。

我不确定与非工作代码的确切区别,但我知道它是正确的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 2014-04-07
    • 2013-02-24
    相关资源
    最近更新 更多