使用信号量条件竞赛同步N个进程



我试图只使用信号量(没有互斥(来订购N个进程。

P1->P2->P3->…->Pn

我正在处理这个问题:

如果您拨打:

s = 1;
P1 {
wait(s1)
...
signal(s1)
}
P2 {
wait(s1)
...
signal(s1)
}

如何防止它不会在一个过程中循环?就像一个释放信号量的进程不会再次接管它一样?我需要所有的过程来最终获得转机。

我也很感激关于如何解决这类问题(同步N个进程(的任何建议ONLY使用信号量,而不使用N个信号量,我读到可能的最小值是3。

谢谢。

以下是一些选项。因为您总是先调用signal,然后再调用wait,所以co-routine选项可能是最好的。您没有可并行的代码,因此无法从普通线程中获益。了解如何避免同步也很有用。

  • 您可以使用多个信号量。在每个线程所在的位置,显式地将控制权交给下一个线程。

  • 你可以有一个谁的回合是下一个变量。获得锁后,线程将检查是否轮到它,如果不轮到它,它将释放锁。这可能导致旋转,什么也不做。所以我们必须再加一把锁。检查后,我们将等待另一个锁完成某些线程。这将在线程完成一些工作后释放。现在线程不旋转了。然而,每当一个线程完成时,每隔一个线程就会检查它是否是下一个。

到目前为止,直接回答您的问题的解决方案是反模式的。你只是在制作一个多线程程序,运行单线程,通过使用信号量来完全同步线程。

这个是下一个图案或反图案,只是一个音符

  • 在Unix上,如果线程占用处理器,并且有其他线程准备运行,那么它最终会被取消调度

更好的方法。

  • 避免同步:
    (请参阅https://www.youtube.com/watch?v=2yXtZ8x7TXw)如果不使用可变变量,那么并发就很容易,而且不需要同步。

  • 考虑管道和过滤器:在这种模式中,线程可以通过管道(fifo(进行通信。为此,您可以使用最小的锁定循环缓冲区(只需确保只将不可变的数据放入缓冲区(|在Unix(如Gnu/Linux(中,可以使用管道和进程。您可以使用fork在一个程序中完成这一切,也可以将多个程序连接在一起(bash是一个很好的工具(。

  • 考虑微线程/协同例程/协作线程:
    有时用几个独立的线程编写程序是很好的。但是,如果线程没有花费大量时间并发运行(例如,因为您总是调用signal; wait(,那么就不需要线程。线程会给代码带来相当大的复杂性。因此,使用协例程(或在系统上调用的协例程(,它们允许您编写几个独立调度的例程,但只有当调用yield时,控制权才会移交给另一个协例程(类似于调用signal; wait,但该机制更倾向于移交给环中的下一个协例行程。

最新更新