gpt4 book ai didi

c++ - std::future 是否等待销毁

转载 作者:太空狗 更新时间:2023-10-29 21:16:04 24 4
gpt4 key购买 nike

问题std::future 在销毁时调用 wait() 或 get() 吗?

示例

void fun()
{
std::future<int> fut = my_thread_pool.submit(some_work);
}//is fut.wait() or fut.get() called? here

最佳答案

发件人:The View from the C++ Standard meeting September 2013 Part 2 of 2.

On the issue that async destructors should not block we devoted a great deal of discussion on it. [..] The only position that received considerable support was [..] giving advisory that future destructors will not block, unless returned from async, making it the notable exception. [..] After significant discussion, the only part that we tried to carry was N3776, an attempt to clarify the position that ~future and ~shared_future don’t block except possibly in the presence of async. There was an attempt to issue a deprecation along the lines of C. Deprecate async without replacement. This motion was actually almost put forward. But [..] it died even before it reached the operating table.

同时检查:N3679: Async() future destructors must wait

The basic issue

Futures returned by async() with async launch policy wait in their destructor for the associated shared state to become ready. This prevents a situation in which the associated thread continues to run, and there is no longer a means to wait for it to complete because the associated future has been destroyed. Without heroic efforts to otherwise wait for completion, such a "run-away" thread can continue to run past the lifetime of the objects on which it depends.

As an example, consider the following pair of functions:

void f() {
vector<int> v;
...
do_parallel_foo(v);
...
}

void do_parallel_foo(vector<int>& v) {
auto fut = no_join_async([&] {... foo(v); return ...; });
a: ...
fut.get();
...
}

If no_join_async() returns a future whose destructor does not wait for async completion, everything may work well until the code at a throws an exception. At that point nothing waits for the async to complete, and it may continue to run past the exit from both do_parallel_foo() and f(), causing the async task to access and overwite memory previously allocated to v way past it's lifetime.

The end result is likely to be a cross-thread "memory smash" similar to that described in N2802 under similar conditions.

This problem is of course avoided if get() or wait() is called on no_join_async()-generated futures before they are destroyed. The difficulty, as in N2802, is that an unexpected exception may cause that code to be bypassed. Thus some sort of scope guard is usually needed to ensure safety. If the programmer forgets to add the scope guard, it appears likely that an attacker could generate e.g. a bad_alloc exception at an opportune point to take advantage of the oversight, and cause a stack to be overwritten. It may be possible to also control the data used to overwrite the stack, and thus gain control over the process. This is a sufficiently subtle error that, in our experience, it is likely to be overlooked in real code.

关于c++ - std::future 是否等待销毁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36197835/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com