Ccriticalsection是否可用于生产?

时间:2010-12-06 11:53:21

标签: multithreading visual-c++ mfc

我们是MFC的几个新手,我们正在构建一个多线程应用程序。我们遇到了URL中的文章,该文章警告我们不要使用CCriticalSection,因为它的实现已被破坏。我们有兴趣知道是否有人有使用CCriticalSection的经验,你是否遇到任何问题或错误?如果我们使用VC ++ 2008构建我们的应用程序,CCriticalSection是否可用并且生产就绪?

http://www.flounder.com/avoid_mfc_syncrhonization.htm

THX

2 个答案:

答案 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)

那篇文章表明使用这些原语的简单情况很好,除了它们的实现违反了它们应该期望的语义。

基本上,它建议如果你把它用作非递归锁,你要注意始终确保锁是有效的(即不被放弃),那么你应该没事。

然而,文章确实抱怨说这些限制是不可原谅的。