什么可能导致单个写入/多读锁的僵局

What could cause a deadlock of a single write/multiple read lock?

本文关键字:读锁 僵局 单个写 什么      更新时间:2023-10-16

我有一个类实例,其他几个类别中的其他几个线程中使用的类实例进行交流。

此类使用纤细的读取器/作者锁(Winapi的SRWLOCK)作为同步对象和几个RAII助手类来实际锁定/解锁事物:

static unsigned int readCounter = 0;
class CReadLock
{
public:
    CReadLock(SRWLOCK& Lock) : m_Lock(Lock) { InterlockedIncrement(&readCounter); AcquireSRWLockShared(&m_Lock);  }
    ~CReadLock() {ReleaseSRWLockShared(m_Lock); InterlockedDecrement(&readCounter);}
private:
    SRWLOCK& m_Lock;
};
class CWriteLock
{
public:
    CWriteLock(SRWLOCK& Lock) : m_Lock(Lock) { AcquireSRWLockExclusive(&m_Lock); }
    ~CWriteLock() { ReleaseSRWLockExclusive(&m_Lock); }
private:
    SRWLOCK& m_Lock;
};

问题一直是僵局。当我暂停僵局的程序时,我会看到:

  • 一个线程卡在AcquireSRWLockExclusive();
  • 两个线程卡在AcquireSRWLockShared();
  • readCounter全局设置为3。

我看到它的方式,唯一的方法是CReadLock实例的驱动器尚未以某种方式称为某个地方,因此锁一直被卡住。但是,(据我所知)唯一发生这种情况的方法是因为抛出了例外。不是。我检查了。

可能是什么问题?我应该如何修复此东西(或至少找到原因)?

您是否以递归方式读取锁?

void foo()
{
    CReadLock rl(m_lock);
    ...
    bar();
}
void bar()
{
    CReadLock rl(m_lock);
    ...
}
void baz()
{
    CWritedLock rl(m_lock);
    ...
}

如果foo()baz()同时称为僵局:

1. (Thread A) foo locks
2. (Thread B) baz asks to create write lock now all read locks would block until all are released - waits.
3. (Thread A) bar tries to lock and waits because there is pending write lock

您有2个线程粘在读取锁上和读取锁定计数器上的事实是3,很可能表明您在其中一个锁中有递归 - 即,一个线程试图获得两次读取锁。

one thread stuck in AcquireSRWLockExclusive();
two threads stuck in AcquireSRWLockShared();
readCounter global is set to 3.

好吧,据我从中读取,您有一个线程持有读取锁,一个写线程等待该读锁的释放,还有两个读取线程等待该写入线程以获取和释放锁。

换句话说,您有一个悬挂的读取线程,它没有像您说的那样破坏蜜蜂。将调试打印添加到破坏者和构造函数。