What is std::atomic and how to use it?
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:
- C++ atomics and memory ordering
- Comparison: Lockless programming with atomics in C++ 11 vs. mutex and RW-locks
- C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?
- Concurrency in C++11
原文还有很多内容。相关例子: 双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.
- WAIT(addr, val) If the value stored at the address addr is val, puts the current thread to sleep.
- WAKE(addr, num) Wakes up num number of threads waiting on the address addr.
- 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
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤