修改为 "Implementing an N process barrier using semaphores"
Modification to "Implementing an N process barrier using semaphores"
最近我看到这个问题与第一个 reader/writer 问题非常相似。
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()
这是正确的吗?
我想知道是否存在一些我没有发现的错误。
你的伪代码正确returns 障碍回到初始状态。无关紧要的建议:替换
barrier.signal()
if(count==0){ barrier.wait()}
恕我直言,更具可读性
if(count!=0){ barrier.signal()} //if anyone left pending barrier, release it
不过,这个方法可能有坑,barrier被复用了。所述屏障有两种状态:
- 停止每个线程,直到所有线程都挂起。
- 恢复每个线程,直到所有线程都运行
没有防止混合它们的保护措施:一些线程正在恢复,而其他线程已经再次进入第一阶段。例如,你有一堆线程,它们做一些事情然后在屏障上同步。每个线程主体将是:
while (!exit_condition) {
do_some_stuff();
pend_barrier(); // implementation from current question
}
程序员预计,do_some_stuff()
的调用次数对于所有线程都是相同的。根据时间可能会(或可能不会)发生什么:从屏障释放的第一个线程在所有线程离开屏障之前完成 do_some_stuff()
计算,因此它第二次重新进入挂起状态。因此,他将与当前屏障释放迭代中的其他线程一起被释放,并将(至少)再调用一次 do_some_stuff()
.
最近我看到这个问题与第一个 reader/writer 问题非常相似。
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()
这是正确的吗?
我想知道是否存在一些我没有发现的错误。
你的伪代码正确returns 障碍回到初始状态。无关紧要的建议:替换
barrier.signal()
if(count==0){ barrier.wait()}
恕我直言,更具可读性
if(count!=0){ barrier.signal()} //if anyone left pending barrier, release it
不过,这个方法可能有坑,barrier被复用了。所述屏障有两种状态:
- 停止每个线程,直到所有线程都挂起。
- 恢复每个线程,直到所有线程都运行
没有防止混合它们的保护措施:一些线程正在恢复,而其他线程已经再次进入第一阶段。例如,你有一堆线程,它们做一些事情然后在屏障上同步。每个线程主体将是:
while (!exit_condition) {
do_some_stuff();
pend_barrier(); // implementation from current question
}
程序员预计,do_some_stuff()
的调用次数对于所有线程都是相同的。根据时间可能会(或可能不会)发生什么:从屏障释放的第一个线程在所有线程离开屏障之前完成 do_some_stuff()
计算,因此它第二次重新进入挂起状态。因此,他将与当前屏障释放迭代中的其他线程一起被释放,并将(至少)再调用一次 do_some_stuff()
.