【问题标题】:How to unblock all threads waiting on a semaphore?如何解除阻塞等待信号量的所有线程?
【发布时间】:2019-03-30 20:17:59
【问题描述】:

我正在处理有限数组(或有限多个缓冲区)的标准生产者和消费者问题。我尝试使用信号量来实现它,但遇到了问题。我希望制片人“生产”只说 50 次。之后我希望生产者线程加入主线程。这部分很简单,但我无法做的是加入消费者线程。他们被困在没有数据的信号量上。我该如何解决这个问题?
一种可能的选择是有一个标志变量,当生产者加入 main 时变为 True,之后,主线程将执行与工作线程数量一样多的 post(semaphore)。工作线程每次唤醒后都会检查标志变量,如果为真,它将退出函数。
我认为我的方法效率很低,因为有许多后信号量调用。如果我可以一次解锁所有线程,那就太好了!
编辑:我尝试实现我所说的一切,但由于死锁而无法正常工作

【问题讨论】:

    标签: multithreading deadlock semaphore producer-consumer


    【解决方案1】:

    一种选择是“毒丸”法。它假设您知道存在多少消费者线程。假设有N个消费者,那么生产者做完这件事后,将N个“毒丸”放入队列中。 “毒丸”只是一个对象/值,它与生产者通常生产的任何东西类型兼容,但与普通对象/值有区别。

    当消费者发现自己吃了毒丸后,它就会死去。问题解决了。

    【讨论】:

      【解决方案2】:

      我仅在 FreeRTOS 操作系统中使用 C++ 完成了生产者消费者结构,因此请记住这一点。到目前为止,这是我在多任务处理方面的唯一经验。我想说我在那个程序中只使用了一个生产者和一个消费者。我已经在 LabView 中完成了多任务处理,但我认为这与您可能拥有的有点不同。

      我认为一种选择可能是拥有一个队列结构,以便生产者将元素排入队列,但如果它充满数据,那么您可以希望实现它,以便您可以制定某种队列策略,如下所示.

      生产者可以

      1. 阻塞自身,直到队列中有空间可入队,
      2. 在一定时间段内阻塞自身,如果花费时间并且未成功将数据入队,则在其他地方继续
      3. 马上去别处

      所以看起来你的排队政策是有序的......

      至少在 FreeRTOS 中,队列读取器能够拥有类似的三种策略。

      一般来说,如果你有一个二进制信号量,那么你就有了它,以便发送方正在发送它,而接收方正在等待它。它用于同步或信令。

      在我看来,您选择了错误的“许多信号量”方法 (???) 你需要的是一个队列结构,生产者在其中输入东西...... 然后,消费者从队列中读取他们必须做的任何事情...... 如果队列为空,那么您需要一个关于队列读取器线程应该做什么的策略。 那些队列读取器和信号量读取器也需要在队列为空或未收到信号量时应该做什么的策略选择。对于这种问题,我不会使用信号量...

      我认为布尔变量的想法可行,因为您只是在生产者线程中写入该变量。如果生产者处于活动状态,那么其他线程应该能够读取和轮询该布尔变量......

      但我认为您应该提供更多详细信息,尤其是消费者线程、您拥有多少线程以及您正在使用哪种语言进行编程等...

      【讨论】:

      • 您尝试过布尔变量技术吗?我认为您至少会避免陷入僵局?我认为您的问题听起来像是某些线程可能正在等待从未给出的信号量。所以听起来每个线程都应该等待自己的信号量,而生产者应该在不能再入队时同时发送所有各自的信号量???
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-03
      相关资源
      最近更新 更多