What exactly is std::atomic?

Is a = a + 12 the entire operation, add_twelve_to(int) atomic? Or are changes made to the variable atomic, operator=() ?

std::atomic<> wraps operations that, in pre-C++ 11 times, had to be performed using (for example) interlocked functions with MSVC or atomic bultins in case of GCC.

Also, std::atomic<> gives you more control by allowing various memory orders that specify synchronization and ordering constraints. If you want to read more about C++ 11 atomics and memory model, these links may be useful:

原文还有很多内容。相关例子: 双buffer实现无锁切换 - 高性能架构探索 - 博客园

c++ - Overhead of pthread mutexes? - Stack Overflow

"A mutex requires an OS context switch. That is fairly expensive." This is not true on Linux, where mutexes are implemented using something called futex'es. Acquiring an uncontested (i.e., not already locked) mutex is, as cmeerw points out, a matter of a few simple instructions, and is typically in the area of 25 nanoseconds w/current hardware.

A futex (short for "fast userspace mutex") is a kernel system call that programmers can use to implement basic locking, or as a building block for higher-level locking abstractions such as semaphores and POSIX mutexes or condition variables.

A futex consists of a kernelspace wait queue that is attached to an atomic integer in userspace. Multiple processes or threads operate on the integer entirely in userspace (using atomic operations to avoid interfering with one another), and only resort to relatively expensive system calls to request operations on the wait queue (for example to wake up waiting processes, or to put the current process on the wait queue). A properly programmed futex-based lock will not use system calls except when the lock is contended; since most operations do not require arbitration between processes, this will not happen in most cases.

Futexes have two basic operations, WAIT and WAKE. A third operation called REQUEUE is available and functions as a more generic WAKE operation that can move threads between waiting queues.

  1. WAIT(addr, val) If the value stored at the address addr is val, puts the current thread to sleep.
  2. WAKE(addr, num) Wakes up num number of threads waiting on the address addr.
  3. CMP_REQUEUE(old_addr, new_addr, num_wake, num_move, val) If the value stored at the address old_addr is val, wakes num_wake threads waiting on the address old_addr, and enqueues num_move threads waiting on the address old_addr to now wait on the address new_addr. This can be used to avoid the thundering herd problem on wake.

原文还有很多内容。Atomic/GCCMM - GCC Wiki (gnu.org)

六级/考研单词: wrap, affection, buffer, overhead, stack, overflow, expense, implement, instruct, hardware, invariable, multiple, thread, interfere, contend, tertiary, thunder, herd

posted on 2022-01-07 09:04  华容道专家  阅读(61)  评论(0)    收藏  举报