admin管理员组文章数量:1122846
The 2020 standard says (23.9.9/4.1):
If launch::async is set in policy, calls invoke(decay-copy(std::forward(f)), decaycopy( std::forward(args))...) (20.14.4, 32.4.3.3) as if in a new thread of execution [...].
Does "as if" in a new thread guarantee that I can use std::mutex
to protect resources accessed by multiple parallel thingies started with async
? It works very well, but that means nothing when it comes to concurrency, does it.
Even though this seems the intent and many tutorials do that, I'm asking because ordinary mutexes absolutely must not be locked twice from the same thread. And because mutexes and threads may map 1:1 to system resources, some magic must be done if two async thingies may interleave on the same system thread and lock the same mutex.1
Tangentially related was a similar issue with thread_local variables in async thingies that were re-using threads from a thread pool. Apparently, the consensus was formed that "as if" here implies "as-if-thread local", i.e., the behavior should indeed completely mimic running on different threads. (Re-using a thread linearly for a next async thingie after some predecessor has finished should not be an issue for mutexes anyway because a thread and presumably also a thingie must not end while still locking a mutex, i.e., all mutexes are unlocked by the time the new thingie starts.)
Presumably, "as if" in a new thread is the case for mutexes as well.
Is it?
1 An example for such interleaving were Java's Green threads which all mapped to the same OS thread.
The 2020 standard says (23.9.9/4.1):
If launch::async is set in policy, calls invoke(decay-copy(std::forward(f)), decaycopy( std::forward(args))...) (20.14.4, 32.4.3.3) as if in a new thread of execution [...].
Does "as if" in a new thread guarantee that I can use std::mutex
to protect resources accessed by multiple parallel thingies started with async
? It works very well, but that means nothing when it comes to concurrency, does it.
Even though this seems the intent and many tutorials do that, I'm asking because ordinary mutexes absolutely must not be locked twice from the same thread. And because mutexes and threads may map 1:1 to system resources, some magic must be done if two async thingies may interleave on the same system thread and lock the same mutex.1
Tangentially related was a similar issue with thread_local variables in async thingies that were re-using threads from a thread pool. Apparently, the consensus was formed that "as if" here implies "as-if-thread local", i.e., the behavior should indeed completely mimic running on different threads. (Re-using a thread linearly for a next async thingie after some predecessor has finished should not be an issue for mutexes anyway because a thread and presumably also a thingie must not end while still locking a mutex, i.e., all mutexes are unlocked by the time the new thingie starts.)
Presumably, "as if" in a new thread is the case for mutexes as well.
Is it?
1 An example for such interleaving were Java's Green threads which all mapped to the same OS thread.
Share Improve this question asked Nov 21, 2024 at 12:38 Peter - Reinstate MonicaPeter - Reinstate Monica 16k4 gold badges41 silver badges67 bronze badges 6 | Show 1 more comment1 Answer
Reset to default 6"as if in a new thread" should be read in the context of a platform-neutral C++ standard. From the C++ perspective, the thread must be new. That includes C++ objects like std::mutex
. But it's unspecified whether std::thread
maps to OS threads, and it's unspecified if OS threads can be reused. As far as the standard is concerned, it's even possible that the OS thread of a std::thread
is reused for std::async
.
本文标签: cstdasync does quotas if in a new threadquot guarantee that it is safe to use mutexesStack Overflow
版权声明:本文标题:c++ - std::async: does "as if in a new thread" guarantee that it is safe to use mutexes? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736310864a1934528.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
std::launch::async
as its first argument, you should not lock the mutex in calling thread. Ifstd::launch::deferred
is specified, the first thread to wait on the future runs the function. If the launch parameter is not specified, platform can choose to deffer. So, if the mutex is not multi-lockable(eg.std::recursive_mutex
), it can only be locked within alaunch::async
call. – Red.Wave Commented Nov 21, 2024 at 15:33future.get()
chain) which is one edge case of allowed execution order anyway. [Hm, at second thought it may be that everything in the main thread is a problem, true!] – Peter - Reinstate Monica Commented Nov 21, 2024 at 16:16