如何通过原子操作实现非原子操作排序以构建高级同步设施?
用原子操作构建自旋锁:高级同步设施的基础
咱们可以通过原子操作来约束非原子操作的执行顺序,这正是构建高级同步工具的核心思路。我先引用Anthony Williams所著《C++ Concurrency in Action》中的一段经典实现:
class spinlock_mutex { std::atomic_flag flag; public: spinlock_mutex(): flag(ATOMIC_FLAG_INIT) {} void lock() { while(flag.test_and_set(std::memory_order_acquire)); } void unlock() { flag.clear(std::memory_order_release); } };
关键逻辑拆解
- lock() 方法:这是一个基于
flag.test_and_set()的自旋循环,采用std::memory_order_acquire内存序。第一个线程调用lock时,flag初始为清空状态,首次调用test_and_set会将flag置位并返回false,意味着线程成功获取锁,循环直接终止,接下来就能安全修改受锁保护的数据。其他线程此时调用lock的话,会发现flag已被置位,只能在循环里不断重试(自旋等待),直到锁被释放。 - unlock() 方法:调用
flag.clear()并使用std::memory_order_release内存序。持有锁的线程完成受保护数据的修改后调用unlock,这里的release语义会和其他线程调用lock时的acquire语义形成同步关系(参考原书5.3.1节)。
这种同步关系的作用至关重要:因为线程对受保护数据的修改必然发生在unlock调用之前,所以这些修改会先于unlock执行;而通过release-acquire的同步绑定,这些修改也会被后续成功获取锁的线程感知到,保证了多线程环境下数据的可见性和操作顺序的正确性。
内容的提问来源于stack exchange,提问作者albizzia
相关产品推荐
相关产品推荐

