c++ - 什么会导致单写/多读锁的死锁?

标签 c++ windows winapi

我有一个类实例,其他线程中的其他几个类使用该类实例进行通信。

这个类使用一个 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/

相关文章:

c++ - 游戏键盘输入和事件

c++ - 使用 OpenCV 进行图像捕获 - 选择超时错误

c++ - 如何使用 C++ 库函数或 STL 对字符串进行排序?

windows - UDP 数据包,被 Wireshark 看到,被(甚至没有到达)WSARecvFrom 丢弃

windows - DirectX 应用程序中 Alt-Tab 支持的最佳实践?

python - 将文件添加到文件夹时如何自动运行python脚本?

c++ - 组合位图/图像列表 (Win32)

c++ - 对象的析构函数导致崩溃

c++ - ADO 和异常处理

c - 我如何使用 Win32 API 启动带参数的进程?