【问题标题】:is Ccriticalsection usable in production?Ccriticalsection 可以在生产中使用吗?
【发布时间】:2011-05-20 22:45:43
【问题描述】:

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

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

谢谢

【问题讨论】:

    标签: multithreading visual-c++ mfc


    【解决方案1】:

    那篇文章建议使用这些原语的简单情况很好,只是它们的实现违反了它们应有的语义。

    基本上,它建议如果您将其用作非递归锁,并注意始终确保锁有效(即未放弃),那么您应该没问题。

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

    【讨论】:

      【解决方案2】:

      我认为这篇文章是基于对 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 的源来验证这种方式。)

      【讨论】:

      • 他对锁应该做什么的理解似乎是基于 comp-sci 背景或来自其他平台和/或实现的类似名称锁的实现,基于他的论点的语气.
      • 他把 CSingleLock 误认为是临界区本身。 CSingleLock 管理一个锁(并为其提供 RAII),而不是整个临界区。
      • 现在,你绝对需要另一个 +1,但你已经得到了我的! :(
      • 我认为他的咆哮是因为突变体(又名互斥体)对象和临界区在 Windows 上都是本机递归的,而 MFC 的包装器对此进行了限制。
      • MFC 的包装器并没有限制递归,据我所知,至少在临界区的情况下(我没有过多地研究互斥体的情况)。您应该能够根据需要多次锁定 CCriticalSection,就像原生 CRITICAL_SECTION 一样。另一方面,每个 CSingleLock 实例只能用于单个锁。您可以将多个 CSingleLock 指向同一个 CCriticalSection,因此这不是问题。 CSingleLock 不是关键部分;这是一个锁。我不使用 MFC,但有自己的关键部分 RAII 包装器,类似于 CSingleLock。
      猜你喜欢
      • 2015-08-26
      • 1970-01-01
      • 2010-09-12
      • 1970-01-01
      • 2011-02-17
      • 1970-01-01
      • 1970-01-01
      • 2017-02-13
      • 1970-01-01
      相关资源
      最近更新 更多