我有一个类实例,其他线程中的其他几个类使用该类实例进行通信。
这个类使用一个 slim reader/writer 锁(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 的事实很可能表明您在其中一个锁中进行了递归 - 即一个线程曾两次尝试获取读锁。
关于c++ - 什么会导致单写/多读锁的死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13064474/