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

时间:2018-11-24 15:40:57

标签: multithreading concurrency process operating-system semaphore

我正在尝试仅使用信号量(不使用互斥锁)对N个进程进行排序。

  

P1-> P2-> P3-> ...-> Pn

我正在处理此问题:

如果您致电:

s = 1;

P1 {
wait(s1)
...
signal(s1)
}

P2 {
wait(s1)
...
signal(s1)
}

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

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

谢谢。

1 个答案:

答案 0 :(得分:0)

以下是一些选项。因为您总是总是紧接着先呼叫signal,然后再呼叫wait,所以协同例程选项可能是最好的。您没有可并行化的代码,因此无法从普通线程中受益。了解避免同步的需求也将很有用。

  • 您可以使用多个信号灯。每个线程在哪里将控制权明确交给下一个线程。

  • 您可以具有Whose-turn-is-next变量。获取锁后,线程将检查是否轮到它了,否则,将释放该锁。这可能导致旋转,什么也不做。因此,我们将不得不添加另一个锁。检查后,我们将等待另一个锁已经完成了某个线程。线程完成某些工作后,将释放此空间。现在线程不旋转。但是,每当一个线程结束时,其他所有线程都会检查它是否是下一个线程。

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

这是一个模式或反模式,只是一个音符

  • 在Unix上,如果线程占用了处理器,则线程最终将被调度,并且还有其他线程可以运行。

更好的方法。

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

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

  • 考虑微线程/协同例程/协同线程:
    有时编写带有多个独立线程的程序会很不错。但是,如果您的线程没有花大量时间并行运行(例如,因为您始终调用signal; wait),那么就不需要线程。线程给代码带来了极大的复杂性。因此,请使用协同例程(或在系统上调用的例程),它们使您可以编写几个独立调度的例程,但是只有在调用yield时,控制权才会移交给另一个协同例程(类似于调用signal; wait,但该机制将更愿意移交给环中的下一个协同例程。