Does std::mutex create a fence?

好久不见. 提交于 2019-11-28 09:38:58

Unlocking a mutex synchronizes with locking the mutex. I don't know what options the compiler has for the implementation, but you get the same effect of a fence.

As I understand this is covered in:

1.10 Multi-threaded executions and data races

Para 5:

The library defines a number of atomic operations (Clause 29) and operations on mutexes (Clause 30) that are specially identified as synchronization operations. These operations play a special role in making assignments in one thread visible to another. A synchronization operation on one or more memory locations is either a consume operation, an acquire operation, a release operation, or both an acquire and release operation. A synchronization operation without an associated memory location is a fence and can be either an acquire fence, a release fence, or both an acquire and release fence. In addition, there are relaxed atomic operations, which are not synchronization operations, and atomic read-modify-write operations, which have special characteristics. [Note: For example, a call that acquires a mutex will perform an acquire operation on the locations comprising the mutex. Correspondingly, a call that releases the same mutex will perform a release operation on those same locations. Informally, performing a release operation on A forces prior side effects on other memory locations to become visible to other threads that later perform a consume or an acquire operation on A. “Relaxed” atomic operations are not synchronization operations even though, like synchronization operations, they cannot contribute to data races. —end note]

Lock and unlock mutexes is only useful if the mutex is shared by different threads. If the compiler knows it isn't the case, as if the mutex is an automatic variable whose address is not taken (nor a reference to it), then no meaningful code needs to be generated for lock/unlock operations.

A lock/unlock mutex operation cannot be a substitute for an "anonymous" (not linked to any particular shared synchronization object) acquire/release operation, which is performed by a call to atomic_thread_fence; but it might appear to always be with current naive compiler support of threads, which effectively provide the atomic_thread_fence equivalent. But when compilers start optimizing away useless locking operations they will break such non-conforming code.

C/C++ thread semantics (*) doesn't allow any substitute for atomic_thread_fence that is correct in general: any code transformation that removes a call to atomic_thread_fence is only correct in context.

(*) "C/C++ thread semantics" not "C/C++ programming language thread semantics": C and C++ are based on the same specification for synchronization primitives, that doesn't mean that there is a C/C++ language)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!