为什么我的带有 boost::future 的链式方法没有被调用?
Why my chained methods with boost::future's .then are not invoked?
我有如下一段代码:
#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
在线资源link(使用 booost 1.58.0 和 gcc 5.3.0)http://melpon.org/wandbox/permlink/G8rqt2eHUwI4nzz8
正如一位伟大的诗人曾经写道,"wait for it"。
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();
});
线程只是建立了一个期货链。它没有运行任何一个。
您启动链(使用您的设置),然后等待链设置(使用连接),但 main 在链完成之前退出。你得到 "lucky",在进程退出前有一个 运行ning。
真的,你应该在主线程中设置链,并在你的线程 t 中等待来自链的最后一个未来。那么你的代码就更有意义了。
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 没有用处的事实:在主线程中用 last.get()
替换 t.join()
并完全删除变量 t
。
如下评论所述,您还调用了两次 get:要使其正常工作,您需要一个 shared_future。这可能就是你的运气 wws 一致的原因,因为第二个 get 可能会阻塞线程。
我有如下一段代码:
#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
在线资源link(使用 booost 1.58.0 和 gcc 5.3.0)http://melpon.org/wandbox/permlink/G8rqt2eHUwI4nzz8
正如一位伟大的诗人曾经写道,"wait for it"。
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();
});
线程只是建立了一个期货链。它没有运行任何一个。
您启动链(使用您的设置),然后等待链设置(使用连接),但 main 在链完成之前退出。你得到 "lucky",在进程退出前有一个 运行ning。
真的,你应该在主线程中设置链,并在你的线程 t 中等待来自链的最后一个未来。那么你的代码就更有意义了。
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 没有用处的事实:在主线程中用 last.get()
替换 t.join()
并完全删除变量 t
。
如下评论所述,您还调用了两次 get:要使其正常工作,您需要一个 shared_future。这可能就是你的运气 wws 一致的原因,因为第二个 get 可能会阻塞线程。