C++部分互斥锁/关键段锁

C++ partial mutex/critical section lock

本文关键字:段锁 C++      更新时间:2023-10-16

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

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

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

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

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

提前感谢,Martin

如果不需要同时保护setter(例如:setPropertyX(value)),那么这可以通过单个信号量和手动重置事件来实现,其中初始资源计数是您要保护的属性数。

在任何给定的设置中:

  • 按设置等待NoUpdatePendingEvent
  • 获取信号量资源(1)
  • 更新属性值
  • 释放信号量资源(1)

在主更新程序中

  • NoUpdatePending事件清除
  • 获取信号量资源(n)
  • 执行更新
  • 释放信号量资源(n)
  • NoUpdatePending事件集

其中(n)是您拥有的属性数。设置了NoUpdatePending的初始状态,等待它不会重置它(因此只需要手动重置)。只要有任何属性正在更新,就不能输入更新。一旦输入Update代码并清除NoUpdatePending事件,传入的prop更新将在该事件上暂停,并且不会消耗信号量资源。所有正在运行的道具集最终都将释放继续更新所需的资源。

尽管如此,仍然单独考虑属性并发性。

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

Update方法中,在进行更新之前获取所有特性特定的关键部分。如果在您更新时有人打电话给setter,这将导致setter现在被阻止。

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

在每个设置器中:

  • 获取关键部分csUpdate
  • 联锁增量(&countSettersActive)
  • 发布关键部分csUpdate
  • 更新属性
  • InterlockedDecrement(&countSettersActive)

在主更新例程中:

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