如何手动创建将在析构函数中阻塞的未来
How to manually create future which will block in destructor
我读过 http://scottmeyers.blogspot.com/2013/03/stdfutures-from-stdasync-arent-special.html 但它没有显示如何实现相同类型行为的示例 - 即未来将在析构函数中阻塞,与从异步返回的析构函数相同但没有使用任何异步。
能举个例子吗?谢谢!
如果您关注该文章下方的评论线程,您会发现其他专家并不同意:
不是来自 async
的 future
应该在析构函数中阻塞。
根据Scott Meyers对标准的解释应该是这样的。
马丁尼奥·费尔南德斯:
I don't see why this is a requirement for all futures: this particular requirement you quote is from the requirements upon std::async
, not the requirements on std::future
. The only requirement on the destructor of std::future
is that it "releases the shared state". It happens that the shared state from std::async
adds the requirement you quote, but no other shared state in the standard library has such a requirement.
赫伯·萨特:
tl;dr: Martinjo already answered this correctly -- the article is not correct, the blocking applies only to futures returned from std::async
with launch policy launch::async
.
Scott said:
and in 30.6.8/5, we see that [...] This is a requirement for any future object, not just the ones returned from std::async
calls.
这不符合。 30.6.8 是 std::async
的规范。 其中所说的任何内容都是针对 std::async
。
但正如 Martinho 已经正确说过的那样,此例外情况仅在第 30.6.8 条中 "Function template async",并且不适用于一般期货。
结论:我不认为你能找到你要找的例子。
很抱歉回答我自己,但只是为了确认问题已得到回答:根据 https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-api-4.5/a00879_source.html 确实是共享状态析构函数阻止了未来本身。
template<typename _Res>
class __future_base::_Async_state : public __future_base::_State
{
public:
typedef _Res _Res_type;
explicit
_Async_state(std::function<_Res()>&& __fn)
: _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)),
_M_thread(mem_fn(&_Async_state::_M_do_run), this)
{ }
~_Async_state() { _M_thread.join(); }
而从 async 返回的 future 恰好使用了这种确切的状态。通过创建一个 class which destructor will join() on some thread 并使用此 class 作为模板参数创建未来,可以实现相同的行为:https://ideone.com/5RAPoA
我读过 http://scottmeyers.blogspot.com/2013/03/stdfutures-from-stdasync-arent-special.html 但它没有显示如何实现相同类型行为的示例 - 即未来将在析构函数中阻塞,与从异步返回的析构函数相同但没有使用任何异步。
能举个例子吗?谢谢!
如果您关注该文章下方的评论线程,您会发现其他专家并不同意:
不是来自
async
的future
应该在析构函数中阻塞。根据Scott Meyers对标准的解释应该是这样的。
马丁尼奥·费尔南德斯:
I don't see why this is a requirement for all futures: this particular requirement you quote is from the requirements upon
std::async
, not the requirements onstd::future
. The only requirement on the destructor ofstd::future
is that it "releases the shared state". It happens that the shared state fromstd::async
adds the requirement you quote, but no other shared state in the standard library has such a requirement.
赫伯·萨特:
tl;dr: Martinjo already answered this correctly -- the article is not correct, the blocking applies only to futures returned from
std::async
with launch policylaunch::async
.Scott said: and in 30.6.8/5, we see that [...] This is a requirement for any future object, not just the ones returned from
std::async
calls.这不符合。 30.6.8 是
std::async
的规范。 其中所说的任何内容都是针对std::async
。但正如 Martinho 已经正确说过的那样,此例外情况仅在第 30.6.8 条中 "Function template async",并且不适用于一般期货。
结论:我不认为你能找到你要找的例子。
很抱歉回答我自己,但只是为了确认问题已得到回答:根据 https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-api-4.5/a00879_source.html 确实是共享状态析构函数阻止了未来本身。
template<typename _Res>
class __future_base::_Async_state : public __future_base::_State
{
public:
typedef _Res _Res_type;
explicit
_Async_state(std::function<_Res()>&& __fn)
: _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)),
_M_thread(mem_fn(&_Async_state::_M_do_run), this)
{ }
~_Async_state() { _M_thread.join(); }
而从 async 返回的 future 恰好使用了这种确切的状态。通过创建一个 class which destructor will join() on some thread 并使用此 class 作为模板参数创建未来,可以实现相同的行为:https://ideone.com/5RAPoA