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

这段Reentrant Lock实现代码是否存在指令重排错误风险?

无锁可重入锁实现的内存顺序与正确性问题分析

待分析的ReentrantLock32实现代码

class ReentrantLock32
 {
  std::atomic<std::size_t> m_atomic;
  std::int32_t m_refCount;

public:
  ReentrantLock32() : m_atomic(0), m_refCount(0) {}

  void Acquire()
   {
    std::hash<std::thread::id> hasher;
    std::size_t tid = hasher(std::this_thread::get_id());

    if (m_atomic.load(std::memory_order_relaxed) != tid)
     {
       std::size_t unlockValue = 0;
       while (!m_atomic.compare_exchange_weak(
        unlockValue,
        tid,
        std::memory_order_relaxed,
        std::memory_order_relaxed))
       {
        unlockValue = 0;
        PAUSE();
       }
      }
      ++m_refCount;
      std::atomic_thread_fence(std::memory_order_acquire);
     }

  void Release() {
   std::atomic_thread_fence(std::memory_order_release);
   std::hash<std::thread::id> hasher;
   std::size_t tid = hasher(std::this_thread::get_id());
   std::size_t actual = m_atomic.load(std::memory_order_relaxed);
   assert(actual == tid);

   --m_refCount;
   if (m_refCount == 0)
    {
     m_atomic.store(0,std::memory_order_relaxed);
    }
 }
//...
}

核心疑问解答

1. 内存栅栏的重排阻止能力

  • release栅栏(memory_order_release):仅能阻止栅栏之前的非原子操作、relaxed原子操作被重排到栅栏之后;无法约束栅栏之后的操作重排到栅栏之前。
  • acquire栅栏(memory_order_acquire):仅能阻止栅栏之后的非原子操作、relaxed原子操作被重排到栅栏之前;无法约束栅栏之前的操作重排到栅栏之后。

2. 同一线程内的操作重排风险

你担心的场景确实存在严重风险:
当线程执行Release()且m_refCount减至0时,代码会执行m_atomic.store(0, relaxed)。但由于该store是relaxed语义,且release栅栏位于函数开头(无法约束后续的store操作),结合编译器或CPU的重排优化,可能出现:
if (m_refCount == 0)判断完成后,同一线程立即调用Acquire()——此时Acquire()中m_atomic.load(relaxed)可能仍读到旧值(当前线程的tid),于是直接跳过CAS逻辑、递增m_refCount;而之前Release()中的store(0)操作被延迟执行,最终将m_atomic设为0。
这会导致锁的互斥性被破坏:当前线程仍持有锁(m_refCount > 0),但m_atomic已被置为0,其他线程可以通过CAS获取锁,引发并发安全问题。

3. 陈旧数据导致的死锁问题

代码中Acquire()的m_atomic.load(relaxed)存在陈旧数据风险:
若当前线程已经持有锁(m_atomic的值是当前线程tid),但由于relaxed加载的可见性问题,load操作读到了旧值0,代码会进入CAS循环。而循环中每次都将unlockValue重置为0,用0去和实际值为tid的m_atomic做CAS对比,必然持续失败,最终导致线程死锁。


内容的提问来源于stack exchange,提问作者Josh Hardman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 11:10:14