为什么我可以多次调用boost::unique_future::get,而不像std::future
Why can I call boost::unique_future::get many times, unlike std::future?
我知道我们不能多次调用std::future::get
,如果我们需要多次调用它,我们应该使用std::shared_future
。
但是我们可以多次调用boost::unique_future::get
,尽管有boost::shared_future
!
void test1()
{
int i, j;
std::future<int> fu1 = std::async([]{ return 42; });
i = fu1.get();
//j = fu1.get(); // error occur
std::cout << i << std::endl;
boost::unique_future<int> fu2 = boost::async([]{ return 43; });
i = fu2.get();
j = fu2.get(); // sucess...?
std::cout << i << ' ' << j << std::endl;
std::cin.get();
}
输出为:
42
43 43
我想了一会儿,然后尝试这个测试代码。
class TestCls
{
public:
TestCls()
{
std::cout << "[TestCls] default constructor" << std::endl;
}
TestCls(const TestCls &other)
{
std::cout << "[TestCls] copy constructor" << std::endl;
}
TestCls(TestCls &&other)
{
std::cout << "[TestCls] move constructor" << std::endl;
}
TestCls &operator =(const TestCls &other)
{
std::cout << "[TestCls] copy assignment" << std::endl;
return *this;
}
TestCls &operator =(TestCls &&other)
{
std::cout << "[TestCls] move assignment" << std::endl;
return *this;
}
};
void test2()
{
TestCls a, b;
std::cout << std::endl << "unique_future test begin" << std::endl;
boost::unique_future<TestCls> fu1 = boost::async([]{ return TestCls(); });
fu1.wait();
std::cout << "first assignment" << std::endl;
a = fu1.get();
std::cout << "second assignment" << std::endl;
b = fu1.get();
std::cout << "unique_future test end" << std::endl;
std::cout << std::endl << "shared_future test begin" << std::endl;
boost::shared_future<TestCls> fu2 = boost::async([]{ return TestCls(); });
fu2.wait();
std::cout << "first assignment" << std::endl;
a = fu2.get();
std::cout << "second assignment" << std::endl;
b = fu2.get();
std::cout << "shared_future test end" << std::endl;
std::cin.get();
}
输出为:
[TestCls] default constructor
[TestCls] default constructor
unique_future test begin
[TestCls] default constructor
[TestCls] move constructor
first assignment
[TestCls] move constructor
[TestCls] move assignment
second assignment
[TestCls] move constructor
[TestCls] move assignment
unique_future test end
shared_future test begin
[TestCls] default constructor
[TestCls] move constructor
first assignment
[TestCls] copy assignment
second assignment
[TestCls] copy assignment
shared_future test end
虽然boost::unique_future
做的是"移动",而不是"复制",但允许多次调用get
..这怎么可能?
(我的boost版本是1.55.0,我的编译器是vc++ 2013)
如果我执行#define BOOST_THREAD_VERSION 4
,则在第二次调用get()
时发生异常。get()
的多次调用是未定义的行为,直到版本3?或者直到版本3才被允许?
从文档中可以清楚地看出,至少有3个宏在你使用的东西中起着重要的作用
BOOST_THREAD_VERSION
设置库的版本,即使在4和3之间有突破性的变化,你似乎也没有问题。
第二个宏是BOOST_THREAD_PROVIDES_FUTURE
,这个宏是一个开关,没有附加值,如果定义它启用"标准"期货,而不是unique_期货,你所说的unique_future
只是一个占位符,在编译时由这个宏定义的东西。
从文件boost/thread/future.hpp
#if defined BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_FUTURE future
#else
#define BOOST_THREAD_FUTURE unique_future
#endif
在文件boost/thread/detail/config.hpp
中你也有BOOST_THREAD_DONT_PROVIDE_FUTURE
,这是另一个默认操作的开关
// PROVIDE_FUTURE
#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE
&& ! defined BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE
#endif
注意否定的!
,这意味着如果你定义了BOOST_THREAD_DONT_PROVIDE_FUTURE
,你应该得到由库记录的"真正的"unique_future
。
你基本上得到了默认的行为,事实上你正在使用库的版本4并不重要。
关于c++ 11及以后版本的边注:
std::async([]{ return 42; });
这在c++ 11中是不好的做法,在c++ 14中是未定义的行为,你应该总是为你的async
指定一个启动策略。
- Cpp-Tuple使用带有变量的get
- 架构决策:返回std::future还是提供回调
- 使用用户定义的参数调用future/async并调用类方法
- 通过 get-Method 访问变量在类外不起作用
- 为什么无论你输入什么,这"while(cin.get(str,3))"只运行一次?
- Boost.Asio/OpenSSL HTTPS GET certificate trouble
- std::future::get()或std::future::wait()是std::thread::join()的替
- 为什么printf会导致与future.get的死锁,而cout则不会?
- 在 std::future::unwrap() 和 std::future::get() 中竞争
- 线程是否真的在调用 std::future::get() 后启动
- 是否可以在调用 future.get() 之前销毁 std::p romise ?
- 程序在使用异步的 Boost.Process 调用 std::future.get() 后挂起
- C++ bad_alloc future.get 上的例外
- c ++如何使我.get() std::future out of a vector.
- std::future.get() 多个调用(来自不同的线程)
- 为什么即使我使用 std::future::get 也需要加入线程
- std::future.get()有时会卡在osx中
- Visual C++ future.get() 返回类型
- 重复调用std::future::get
- 为什么我可以多次调用boost::unique_future::get,而不像std::future