首先请原谅我的英语很差而且很基础。
阅读“信号量小书”时,我遇到了 Barrier 模式,为了完整起见,我很快记住了它在 Wikipedia: pattern barrier 中的描述:
<块引用>“源代码中一组线程或进程的屏障意味着任何线程/进程必须在此时停止,并且在所有其他线程/进程到达此屏障之前无法继续。” >
作者针对此类问题提出以下解决方案:
mutex = semaphore{1};
barrier = semaphore{0};
count = 0; // shared variable
N is the number of process/thread
(1) rendezvous(); // generic code that each process/thread must
// executes before encountering the barrier
(2) mutex.wait();
(3) count = count + 1;
(4) mutex.signal();
(5) if (count == N)
(6) barrier.signal();
(7) barrier.wait();
(8) barrier.signal();
(9) proceed_to_the_end(); // generic code that each process/thread must
// executes after passing the "barrier"
为了实践我自己设计的问题,以下解决方案:
mutex = semaphore{1};
barrier = semaphore{0};
count = 0; // shared variable
N is the number of process/thread
(1) rendezvous(); // generic code that each process/thread must
// executes before encountering the barrier
(2) mutex.wait();
(3) count = count + 1;
(4) mutex.signal();
(5) if (count < N)
(6) barrier.wait();
(7) barrier.signal();
(9) proceed_to_the_end(); // generic code that each process/thread must
// executes after passing the "barrier"
我比较了这两种解决方案,在我看来它们是等效的,但这是我的观点,我的分析结果,当然它们可能是错误的: 我需要比较我的观点。
您能帮我找出差异(如果存在)吗?
您能找到区分这两种解决方案的一些小技巧吗?
最好的问候并感谢您的时间
答案 0 :(得分:1)
最后一个到达屏障的线程在作者的版本中做了一个额外的信号并等待。你的版本忽略了这些,考虑到作者的解决方案很好,也很好,因为在没有干预操作的时间表中,这对没有影响。
版本之间的功能差异是你的总是先发布最后一个线程,而作者的可以按任意顺序释放线程。
作为旁注,如果你实现了这个,那么第 5 行的 count 读取最好是原子的(如果你在一个顺序不一致的处理器上实现这个,这就是 ~ 全部在这一点上,那么那些信号量操作最好有获取/释放内存栅栏)。