关键部分负锁定计数

ana*_*and 11 deadlock

我正在调试死锁问题,调用堆栈显示线程正在等待某些事件.

代码使用临界区作为同步原语我觉得这里有一些问题.此外,调试器指向一个其他线程拥有的关键部分,但锁定计数为-2.根据我的理解,锁定计数> 0表示关键部分被一个或多个线程锁定.

那么有没有可能我正在寻找可能是死锁的罪魁祸首的正确的关键部分.

在哪些情况下,关键部分可能具有负锁定计数?

Sum*_*uma 25

注意:自从Windows Server 2003(对于客户端操作系统,这是Vista和更新版本),LockCount的含义已经改变,-2是一个完全正常的值,通常见于线程进入临界区而没有等待而没有其他线程在等待CS.请参阅显示关键部分:

在Microsoft Windows Server 2003 Service Pack 1和更高版本的Windows中,LockCount字段的解析方式如下:

  • 最低位显示锁定状态.如果该位为0,则临界区被锁定; 如果为1,则临界区未锁定.
  • 下一位显示是否已为此锁定唤醒线程.如果该位为0,则该锁已被唤醒; 如果是1,则没有线程被唤醒.
  • 其余位是等待锁定的线程数的补码.

  • 我没有在其他地方看到的精彩信息.帮助我解决了关键部分的一些奇怪的行为. (3认同)
  • 同意@ mistiano的评论.我不知道微软改变了LockCount在Server 2003及以上版本中的工作方式.这个链接非常有用! (2认同)

Nav*_*een 6

我假设你在谈论MFC中的CCriticalSection类.我认为你正在寻找合适的关键部分.我发现如果对Lock()函数的调用次数少于Unlock()调用次数,则临界区的锁定计数可能为负.我发现这通常发生在以下类型的代码中:

void f()
{
   CSingleLock lock(&m_synchronizer, TRUE);
   //Some logic here
   m_synchronizer.Unlock();
}
Run Code Online (Sandbox Code Playgroud)

乍一看,这段代码看起来非常安全.但请注意,我直接使用CCriticalSection的Unlock()方法而不是CSingleLock的Unlock()方法.现在发生的是当函数退出时,其析构函数中的CSingleLock再次调用临界区的Unlock()并且其锁定计数变为负数.在此之后,应用程序将处于糟糕的状态,并且奇怪的事情开始发生.如果您正在使用MFC关键部分,请检查此类问题.