C ++部分互斥锁/临界区锁

时间:2012-10-16 06:53:17

标签: c++ events mutex critical-section

我在VS2010中使用C ++工作,我有一个带有一堆属性(getter和setter)的容器类(实际上是一堆具有属性的对象 - 但是让我们简化它并假设它只是一个属性直接在容器类。

在这个容器类上有一个Update函数,重要的是在执行Update方法时阻塞setters方法。

该应用程序是多线程的,所以我想使用互斥/事件/关键部分来处理这个问题。

我的问题是:如何在Update方法运行时锁定/阻止setter,而不让setter方法相互阻塞?此外,我还需要setter来阻止Update方法。

换句话说,我需要一个正常的Critical Section机制,除了setter不应该相互阻塞。

提前致谢, 马丁

3 个答案:

答案 0 :(得分:3)

如果不需要同时保护setter(例如:setPropertyX(value)),则可以使用单个信号量和手动重置事件,其中初始资源计数是您所属的属性数防范。

在任何给定的二传手中:

  • 等待设置NoUpdatePendingEvent。
  • 获取信号量资源(1)
  • 更新属性值
  • 发布信号量资源(1)
主更新例程中的

  • NoUpdatePending事件清除
  • 获取信号量资源(n)
  • 更新
  • 发布信号量资源(n)
  • NoUpdatePending事件集

其中(n)是您拥有的属性数。 NoUpdatePending的初始状态已设置,等待它将不会重置它(因此仅限手动重置要求)。只要更新任何属性,就无法输入更新。一旦输入更新代码并清除NoUpdatePending事件,传入的prop-updates将在事件上停止并且不消耗信号量资源。所有正在运行的prop-sets最终将释放更新所需的资源以继续。

所有这些都说,仍然单独考虑属性并发。

答案 1 :(得分:2)

您可以为每个属性设置一个关键部分。在setter中,您获得了特定于属性的关键部分并完成了您的工作,这样每个属性都不会相互阻塞。

Update方法中,在执行更新之前获取所有特定于属性的关键部分。如果有人在您更新时调用它们,这将导致设置者现在阻止。

答案 2 :(得分:0)

这是一个只使用关键部分和整数的选项,而不关心你有多少个setter:

在每个二传手中:

  • 获取关键部分csUpdate
  • InterlockedIncrement(安培; countSettersActive)
  • 发布关键部分csUpdate
  • 更新资产
  • InterlockedDecrement(安培; countSettersActive)
主更新例程中的

  • 获取关键部分csUpdate
  • while(InterlockedCompareExchange(& countSettersActive,0,0)!= 0){sleep(1); }
  • 做更新
  • 发布关键部分csUpdate