修改为“使用信号量实现 N 进程屏障”

Posted

技术标签:

【中文标题】修改为“使用信号量实现 N 进程屏障”【英文标题】:Modification to "Implementing an N process barrier using semaphores" 【发布时间】:2017-06-02 08:45:14 【问题描述】:

最近我看到这个问题与 First reader/writer problem 非常相似。

Implementing an N process barrier using semaphores

我正在尝试修改它以确保它可以重复使用并正常工作。

n = the number of threads
count = 0
mutex = Semaphore(1)
barrier = Semaphore(0)


mutex.wait()
count = count + 1
if (count == n) barrier.signal()
mutex.signal()

barrier.wait()

mutex.wait()
count=count-1
barrier.signal()
if(count==0) barrier.wait()
mutex.signal()

这是正确的吗?

我想知道是否存在一些我没有发现的错误。

【问题讨论】:

【参考方案1】:

您的伪代码正确地将屏障返回到初始状态。无关紧要的建议:替换

barrier.signal()
if(count==0) barrier.wait()

恕我直言,更具可读性

if(count!=0) barrier.signal() //if anyone left pending barrier, release it

但是,重用屏障的方式可能存在陷阱。描述的屏障有两种状态:

    停止每个线程,直到所有线程都处于挂起状态。 恢复每个线程,直到所有线程都运行

没有防止混合它们的保护:一些线程正在恢复,而其他线程已经再次到达第一阶段。例如,你有一堆线程,它们做一些事情,然后在屏障上同步。每个线程体将是:

while (!exit_condition) 
  do_some_stuff();
  pend_barrier(); // implementation from current question

程序员预计,所有线程对do_some_stuff() 的调用次数都相同。根据时间可能(或可能不会)发生什么:从屏障释放的第一个线程在所有线程离开屏障之前完成do_some_stuff() 计算,因此它第二次重新进入挂起。因此,他将与当前屏障释放迭代中的其他线程一起被释放,并且将(至少)再调用一次do_some_stuff()

【讨论】:

非常感谢!那如果我使用另一个信号量“size=semaphore(n)”和size.wait(),来控制入口。并使用“if(count==0) for(i=1~n)size.signal()" 刷新它。对吗?

以上是关于修改为“使用信号量实现 N 进程屏障”的主要内容,如果未能解决你的问题,请参考以下文章

grafana 修改为HTTPS方式登录

iOS微信更新,改微信号深色模式开关等都来了~

仅使用整数数学修改C中正弦信号的形状

python网络编程--管道,信号量,Event,进程池,回调函数

修改BIOS方法综合

怎么修改linux中sem的值