我编写了这个示例代码来测试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。
应该在函数f.then()
的{{1}}处阻止执行,因为类型bar()
的临时变量应该在销毁时阻塞,输出应该
boost::future<void>
在我的应用程序中,对3405691582
Should have blocked?
的调用阻止执行,直到不调用continuation。
这里发生了什么?
答案 0 :(得分:1)
请注意,在std::async
启动策略为launch::async
的情况下使用~future
时,唯一一次将在析构函数中阻止的时间用于记录。
请参阅Why is the destructor of a future returned from `std::async` blocking?
答案列出了围绕这一主题进行的许多讨论。提案N3776使其成为C ++ 14:
本文提供了实施积极的SG1草案调查的建议措辞,以澄清
~shared_future
和.then
除非存在异步,否则不会阻止。
cppreference.com文件std::async
您的代码从未使用异步,因此如果将来派生的将阻止销毁,那将会令人惊讶。
更一般
很明显,很明显,共识是阻止破坏是一个不幸的设计瑕疵,而不是你期望在更新的扩展上引入的东西(例如key
延续)。
我只能假设这是一个文档错误的情况,其中的措辞
- 返回的期货表现为从boost :: async返回的期货,从那时返回的未来对象的析构函数将被阻止。这可能会在未来的版本中发生变化。
应该删除。