c++ - 为什么我的带有 boost::future's .then 的链式方法没有被调用?

标签 c++ c++11 boost future

我有以下代码:

#define BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION

#include <iostream>
#include <thread>
#include <boost/thread/future.hpp>

using namespace boost;

int foo(boost::future<int> x) {
  std::cout << "first stage(" << x.get() << ")" << '\n';
  return x.get();
}

int main()
{
  std::cout << "making promise" << '\n';
  boost::promise<int> p;
  boost::future<int> f = p.get_future();
  std::cout << "future chain made" << '\n';
  std::thread t([&](){
    f.then(foo)
      .then([](boost::future<int> x){ std::cout << "second stage " << 2 * x.get() << '\n'; return 2 * x.get(); })
      .then([](boost::future<int> x){ std::cout << "final stage " << 10 * x.get() << '\n'; });
  });

  std::cout << "fulfilling promise" << '\n';
  p.set_value(42);
  std::cout << "promise fulfilled" << '\n';

  t.join();
}

然后我这样编译它:

g++ -g -Wall -std=c++14 -DBOOST_THREAD_VERSION=4 main.cpp -lboost_thread -lboost_system -pthread

我得到以下输出:

making promise
future chain made
fulfilling promise
promise fulfilled
first stage(42)

为什么我在线程 t 中链接的 2 个 lambda 没有被调用?我错过了什么吗?

我尝试添加 boost::future::get() 调用,但我得到一个异常:

  std::cout << "fulfilling promise" << '\n';
  p.set_value(42);
  std::cout << "promise fulfilled" << '\n';

  std::cout << "value " << f.get() << '\n';

  t.join();

错误:

making promise
future chain made
fulfilling promise
promise fulfilled
first stage(42)
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::future_uninitialized> >'
  what():  Operation not permitted on an object without an associated state.
[1]    20875 abort      ./main

我正在使用 boost 1.58.0 和 gcc 5.4.0

在线源链接(使用 booost 1.58.0 和 gcc 5.3.0)http://melpon.org/wandbox/permlink/G8rqt2eHUwI4nzz8

最佳答案

正如一位伟大的诗人曾经写过的那样,“等待它”。

std::thread t([&](){
  f.then(foo)
  .then([](boost::shared_future<int> x){ std::cout << "second stage " << 2 * x.get() << '\n'; return 2 * x.get(); })
  .then([](boost::shared_future<int> x){ std::cout << "final stage " << 10 * x.get() << '\n'; })
  .get();
});

线程除了建立一个 future 链外什么都不做。它不运行它们中的任何一个。

您启动链(使用您的集合),然后等待链被设置(使用连接),但是在链完成之前 main 退出。你很“幸运”,在进程退出之前运行了一个。

真的,你应该在主线程中设置链,并在你的线程 t 中等待来自链的最后一个 future 。那么您的代码就更有意义了。

auto last = f.then(foo)
  .then([](boost::shared_future<int> x){ std::cout << "second stage " << 2 * x.get() << '\n'; return 2 * x.get(); })
  .then([](boost::shared_future<int> x){ std::cout << "final stage " << 10 * x.get() << '\n'; });

std::thread t([&](){
  last.get();
});

这突出了线程 t 没有用处的事实:在主线程中将 t.join() 替换为 last.get() 并删除变量 t 完全。

正如下面评论中所指出的,您还调用了两次 get:要使其正常工作,您需要一个 shared_future。这可能就是为什么你的运气 wws 始终如一的原因,因为第二个 get 可能会阻塞线程。

关于c++ - 为什么我的带有 boost::future's .then 的链式方法没有被调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38419860/

相关文章:

c++ - 将 boost::bimap 转换为 std::map

c++ - boost 线程链接在 Netbeans 7.1 调试/测试 session 中失败

c++ - 传递回调成员函数的高效方法

c++ - 针对过时的模板显式实例进行编译

c++ - 这是一种击败省略以保持 dtor 副作用的方法吗?

c++11:子类成员函数的 std::bind

c++ - 在默认初始化程序中使用 lambda 与使用成员函数

c++ - 使用任意类型的给定参数进行任意操作的任何建议?

c++ - 从 Byte * 到 unsigned int 的 memcpy 是反转字节顺序

c++如何在内部循环中使用带自动的 vector 删除对象