You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非无锁std::atomic能否使用SeqLock替代现有自旋锁实现?

在MSVC STL和LLVM libc++的实现中,不满足原生原子大小的std::atomic都是基于自旋锁实现的。

libc++实现代码如下:

_LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
  while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
      /*spin*/;
}
_LIBCPP_INLINE_VISIBILITY void __lock() const {
  while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
      /*spin*/;
}

MSVC实现代码如下:

inline void _Atomic_lock_acquire(long& _Spinlock) noexcept {
#if defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))
    // 算法来自2020年5月发布的《英特尔64和IA-32架构优化参考手册》
    // 示例2-4 带递增退避的竞争锁优化版本,第2-22页
    // 上述手册中的代码采用0BSD许可证发布
    int _Current_backoff   = 1;
    const int _Max_backoff = 64;
    while (_InterlockedExchange(&_Spinlock, 1) != 0) {
        while (__iso_volatile_load32(&reinterpret_cast<int&>(_Spinlock)) != 0) {
            for (int _Count_down = _Current_backoff; _Count_down != 0; --_Count_down) {
                _mm_pause();
            }
            _Current_backoff = _Current_backoff < _Max_backoff ? _Current_backoff << 1 : _Max_backoff;
        }
    }
#elif
/* ... */
#endif
}

我在思考更优实现方案时产生了两个疑问:

  • 能否用SeqLock替代上述自旋锁实现,优势是读写无冲突时读操作成本极低
  • SeqLock能否结合OS等待机制优化,比如当读者观测到奇数序列号时,通过原子等待底层机制(Linux futex/Windows WaitOnAddress)等待,避免自旋锁的饥饿问题

我个人认为该方案是可行的:虽然当前C内存模型未覆盖SeqLock,但std::atomic要求承载类型必须可平凡拷贝,因此seqlock中使用memcpy进行读写是可行的,只要搭配足够的内存屏障实现类似volatile的效果且不会过度影响优化即可。而且这属于特定C实现的头文件内部逻辑,不需要满足跨平台可移植要求。

现有C++实现SeqLock的相关参考问答:

  • 用32位原子实现64位原子计数器
  • 如何用C++11原子库实现seqlock

内容的提问来源于stack exchange,提问作者Alex Guteniev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 08:36:02