我们是MFC的几个新手,我们正在构建一个多线程应用程序。我们遇到了URL中的文章,该文章警告我们不要使用CCriticalSection,因为它的实现已被破坏。我们有兴趣知道是否有人有使用CCriticalSection的经验,你是否遇到任何问题或错误?如果我们使用VC ++ 2008构建我们的应用程序,CCriticalSection是否可用并且生产就绪?
http://www.flounder.com/avoid_mfc_syncrhonization.htm
THX
答案 0 :(得分:11)
我认为这篇文章是基于对CSingleLock的基本误解以及如何使用它。
你不能多次锁定同一个CSingleLock,但你不应该这样做。顾名思义,CSingleLock用于锁定ONCE。
每个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的来源来验证这种方式。)
答案 1 :(得分:0)
那篇文章表明使用这些原语的简单情况很好,除了它们的实现违反了它们应该期望的语义。
基本上,它建议如果你把它用作非递归锁,你要注意始终确保锁是有效的(即不被放弃),那么你应该没事。
然而,文章确实抱怨说这些限制是不可原谅的。