The Little Book of Semaphores 信号量小书 第五章 稍欠经典的同步问题 5.7 过河问题

第五章 稍欠经典的同步问题

 

5.7 过河问题

这个问题来自于加州大学伯克利分校的安东尼·约瑟夫写的问题集,但我不知道他是不是原作者。 它类似于H2O问题,因为它是一种特殊的屏障,只允许线程以某种组合通过。

 在华盛顿州雷德蒙德附近,有一艘划艇,Linux黑客和微软员工(农奴)都用它来过河。渡船能容纳四人,不会离岸。为了保证乘客的安全,不允许把一个黑客加三个农奴或者一个农奴加三个黑客放在船上。其他任何组合都是安全的。

当每个线程登上船时,它应该调用一个叫做board的函数。 您必须保证船上的所有四个线程都要在下一次船载的任何线程之前调用board。

在所有四个线程都调用了board之后,其中只有一个要调用一个名为rowBoat的函数,表明该线程将拿桨划船。 是哪一个线程调用该函数并不重要,只要有一个调用了即可。

不要担心旅行的方向。 假设我们只对其中一个方向的交通感兴趣。

 

5.7.1 过河提示

以下是我在解决方案中使用的变量:

hackers和serfs计算等待登船的黑客和农奴的数量。 由于它们都受互斥锁保护,因此我们可以检查两个变量的状况,而不必担心不合时宜的更新。 这是记分牌的另一个例子。

hackerQueue和serfQueue允许我们控制通过的黑客和农奴的数量。 屏障确保所有四个线程在队长调用rowBoat之前调用了board。

isCaptain是一个局部变量,指示哪个线程应该调用row。

 

5.7.2 过河方案

这个解决方案的基本思想是每个到达的线程更新一个计数器,然后检查它是否构成完整的互补,或者作为其种类的第四个,或者完成一个混合组。

我将介绍黑客的代码; 农奴的代码是对称的(当然,除了它大1000倍,充满了bug,包含一个嵌入式Web浏览器):

当每个线程通过互斥部分时,它会检查是否有完整的船员准备登船。 如果是,它会向相应的线程发出信号,声明自己是队长,并持有互斥锁,以便阻止其他的额外线程,直到船启航。

屏障记录了已登船的线程数。 当最后一个线程到达时,所有线程都会继续运行。 船长调用row,然后(最后)释放互斥锁。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值