Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 同步资源访问_C++_Windows_Multithreading_Thread Safety - Fatal编程技术网

C++ 同步资源访问

C++ 同步资源访问,c++,windows,multithreading,thread-safety,C++,Windows,Multithreading,Thread Safety,我的问题是: 我有一个“引擎”线程,它持续使用一个资源(由引擎拥有)。其他线程可能希望访问该资源,在这种情况下,它们应该告诉引擎暂停并等待,直到完成为止。但是,我不确定用可用的同步原语实现这一点的最佳方式是什么(假设使用Windows,尽管从透视图上看,我可能还需要支持其他平台) 在最简单的情况下,引擎将运行一个循环,该循环进入临界段,进行一些工作,然后离开该段。然而,由于关键部分不是先到先得的,所以其他试图进入该部分的线程可能会永远卡住 在我以前的解决方案中,我创建了一个通常发出信号的事件对象

我的问题是:

我有一个“引擎”线程,它持续使用一个资源(由引擎拥有)。其他线程可能希望访问该资源,在这种情况下,它们应该告诉引擎暂停并等待,直到完成为止。但是,我不确定用可用的同步原语实现这一点的最佳方式是什么(假设使用Windows,尽管从透视图上看,我可能还需要支持其他平台)

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

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


我可以简单地使用一个整数计数器,并通过互锁操作递增/递减它,但是引擎线程必须通过循环等待计数器为零,这是在浪费执行时间。使用整数计数器、事件和临界段的“混合”方法似乎太复杂,不适合作为正确的解决方案。

我认为最好的解决方案可能是使用“等待到零”操作的线程安全计数器。发动机工作如下:

  • 拿到锁
  • 如果计数器不为零,释放锁,等待计数器为零,然后转至步骤1
  • 做一些工作
  • 转至步骤2
  • 要访问对象,请执行以下操作:

  • 递增计数器
  • 拿到锁
  • 访问对象
  • 松开锁
  • 减小计数器的数值

  • 你是说引擎在资源上有无限多的工作要做吗?是的;在我以前的项目中,它正在运行一个渲染循环,其他线程暂停它以修改“状态”;这次是一个执行脚本的解释器。您可以尝试使用互斥锁。我的理解是,他们比关键部分更公平,尽管仍然不是严格的先进先出;但是,如果不运行简单的
    while(c>0),我如何等待计数器为零循环?您必须实现可等待计数器。一种简单的方法是使用锁和事件。当你减少计数器时,如果你把它减少到零,在你释放锁之前解除阻塞事件。所以基本上我提到的最后一个解决方案,包括一个计数器,一个事件和一个临界区?我真的很希望有一个解决方案不涉及这三个方面,但我想这可以。我相信你可能会找到摆脱某些东西的方法,但它们会更复杂,更难理解。我会使用原子计数器和
    std::condition\u variable\u any
    以及
    mutex