这是关于“信号量的小书”第二版的解决方案。作者:Allen B. Downey。我觉得本书(第3.7.4节)中“独占队列”的解决方案可能不正确。但是,由于这不太可能,我请求您的反馈。 下面我提供了充足的背景信息,以便您可以在不参考GNU版权在线提供的图书的情况下做出回应。
顺便说一句,这与任何课程作业无关
问题陈述:
对于交谊舞,有许多舞者被分类为领袖和追随者,随机到达。我们需要强制执行的是,最多只有一对跳舞,并且该对必须包括领导者和追随者。 例如,如果许多领导人到达,他们必须等待粉丝配对。在这一点上,如果许多粉丝到来,他们仍然不能成对地进行,而只有一对人在休息等待时跳舞。 我们被允许使用信号量(除了需要的共享和局部变量)以应用同步约束。
信号量被定义为一个实体,其值可以通过' signal '原子地递增(通过单位),也可以通过'原子递减(通过单位)递减。等待'命令但无法读取其当前值。此外,'等待',在递减后,如果结果为负值,则调用线程将被阻止。另一方面,除了递增之外,每个'信号'将始终唤醒(解除阻塞)其中一个等待(阻塞)线程(如果有的话)。信号量可以用任何整数值初始化 - 零或正或负。
有了这个,本书的解决方案如下(书中列出3.18和3.19)。
书中的解决方案:
'互斥'和队列都是信号量。 'mutext'初始化为'1',而两个队列都初始化为'0'。共享变量'leader'和'followers'都用'0'
初始化 Leader Follower
====== ========
1 mutex.wait() mutex.wait()
2 if followers > 0 if leaders > 0
3 followers-- leaders--
4 followerQueue.signal() leaderQueue.signal()
5 else else
6 leaders++ followers++
7 mutex.signal() mutex.signal()
8 leaderQueue.wait() followerQueue.wait()
9 end-if end-if
10 dance() dance()
11 mutex.signal()
我的关注:
基于上述解决方案,为了强制执行任何新对,直到当前对完成,只有当前对中的一个将发出'信号'(领导者的第11行)他们的舞蹈(第10行)。
但是,我可以想象一种可能违反约束的情况,只有一对跳舞,并且这对必须由每个类别中的一个组成 - 领导者和追随者。
想象一下,很少有领导者先到达,所有人都会等待 leaderQueue (第8行)。在这一点上,一个跟随者,比如F1,到了。 F1将获得 mutex 并唤醒领导者,比如说L1,他们两个都会继续跳舞。 F1仍然持有互斥锁(其当前值设置为'0')。有趣的是,有点夸张,领导者(比如说L1)跳舞并完成;甚至接着表示,当追随者F1仍在准备跳舞时,这对完成了。 互斥锁现在为'1',想象另一个追随者,比如F2,到达。 F2现在将获得互斥锁并唤醒另一位领导者,比如L2。 F2和L2都继续跳舞,而F1还没有完成跳舞。因此,我们的情况违反了所希望的约束条件,即一次只跳一对。
如果我遗失了什么,请告诉我。
P.S。我真诚地感谢唐尼教授这本精彩的书