【问题标题】:Synchronizing resource access同步资源访问
【发布时间】:2013-11-25 16:22:54
【问题描述】:

这是我的问题:

我有一个“引擎”线程,它持续使用资源(由引擎拥有)。其他线程可能想要访问资源,在这种情况下,它们应该告诉引擎暂停并等待它们完成。但是,我不确定使用可用的同步原语实现它的最佳方法是什么(假设是 Windows,但从角度来看,我可能还需要支持其他平台)。

在最简单的情况下,引擎会运行一个循环,进入临界区,做一些工作,然后离开该区。但是,由于关键部分不是先到先服务,因此试图进入该部分的其他线程可能会永远卡住。

在我之前的解决方案中,我创建了一个通常发出信号的事件对象,并且引擎会在每次进入临界区之前等待该事件。另一个线程将重置事件,然后进入该部分,做一些工作,离开该部分并发出事件信号。但是,如果我有多个(其他)线程试图访问资源,这将不起作用,因为事件对象没有计数器。

我可以简单地使用整数计数器并通过互锁操作对其进行递增/递减,但是引擎线程将不得不通过循环等到计数器为零,这会浪费执行时间。同时使用整数计数器、事件和临界区的“混合”方法似乎过于复杂,无法成为正确的解决方案。

【问题讨论】:

  • 你是说引擎在资源上有无限量的工作要做吗?
  • 是的;在我之前的项目中,它正在运行渲染循环,其他线程暂停它以修改“状态”;这次它是一个执行脚本的解释器。
  • 您可以尝试使用互斥锁。我的理解是它们比关键部分更公平,尽管仍然不是严格的 FIFO。

标签: c++ windows multithreading thread-safety


【解决方案1】:

我认为最好的解决方案可能是具有“等到零”操作的线程安全计数器。引擎运行如下:

  1. 获取锁。
  2. 如果计数器不为零,则释放锁,等待计数器为零,然后转到步骤 1。
  3. 做一些工作。
  4. 转到第 2 步。

访问对象:

  1. 增加计数器。
  2. 获取锁。
  3. 访问对象。
  4. 释放锁。
  5. 递减计数器。

【讨论】:

  • 是的,这就是我的想法;但是,如果不运行简单的while(c>0) ; 循环,我将如何等到计数器为零?
  • 你必须实现等待计数器。一种简单的方法是使用锁和事件。当你递减计数器时,如果你递减到零,在你释放锁之前解除阻塞事件。
  • 所以基本上我提到的最后一个解决方案涉及计数器、事件和临界区?我真的希望有一个不涉及所有这三个的解决方案,但我想这会做到。
  • 我相信您可能会找到摆脱某些东西的方法,但它们会更加复杂且难以理解。
  • 我会使用原子计数器和std::condition_variable_any 以及mutex
猜你喜欢
  • 2021-02-05
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多