我认为这篇文章是基于对 CSingleLock 的用途和使用方法的根本误解。
您不能多次锁定同一个 CSingleLock,但您不应该这样做。 CSingleLock,顾名思义,就是用来锁定某物一次。
每个 CSingleLock 只管理其他对象上的一个锁(例如,您在构造过程中传递它的 CCriticalSection),目的是在 CSingleLock 超出范围时自动释放该锁。
如果你想多次锁定底层对象,你会使用多个 CSingleLocks;您不会使用单个 CSingleLock 并尝试多次锁定它。
错误(他的例子):
CCriticalSection crit;
CSingleLock lock(&crit);
lock.Lock();
lock.Lock();
lock.Unlock();
lock.Unlock();
对:
CCriticalSection crit;
CSingleLock lock1(&crit);
CSingleLock lock2(&crit);
lock1.Lock();
lock2.Lock();
lock2.Unlock();
lock1.Unlock();
更好(这样你就可以得到 RAII):
CCriticalSection crit;
// Scope the objects
{
CSingleLock lock1(&crit, TRUE); // TRUE means it (tries to) locks immediately.
// Do stuff which needs the lock (if IsLocked returns success)
CSingleLock lock2(&crit, TRUE);
// Do stuff which needs the lock (if IsLocked returns success)
}
// crit is unlocked now.
(当然,你永远不会在这样的单个块中故意在同一个底层临界区上获得两个锁。这通常只会发生在调用函数的结果中,这些函数在已经拥有的其他东西中获得了锁自己的锁。)
(另外,您应该检查 CSingleLock.IsLocked 以查看锁定是否成功。为了简洁起见,我将这些检查排除在外,因为它们被排除在原始示例之外。)
如果 CCriticalSection 本身也遇到同样的问题,那肯定是个问题,但他没有提供我能看到的证据。 (也许我错过了一些东西。我在 MFC 安装中也找不到 CCriticalSection 的源来验证这种方式。)