第七章 不太遥远的经典问题
7.4 参议院巴士问题
这个问题最初是基于韦尔斯利学院的参议院巴士问题。 乘客到公共汽车站来等公共汽车。 当公共汽车到达时,所有等候的乘客都会调用boardBus,但是在公共汽车上客时到达的任何人都必须等待下一班公共汽车。 公交车的容量为50人; 如果有超过50人等待,有些人将不得不等待下一班车。
当所有等待的乘客上车后,公共汽车可以调用depart。 如果公共汽车到达时没有乘客,它应立即离开。
思考:编写强制执行所有这些约束的同步代码。
7.4.1 巴士问题提示
以下是我在解决方案中使用的变量:
互斥体mutex保护riders,riders跟踪有多少乘客在等待; multiplex确保上客区不超过50名乘客。
乘客等待bus信号,公共汽车到达时会发出该信号。 公共汽车等待allAboard信号,它由最后一位乘客发出该信号。
7.4.2 巴士问题方案-1#
下面是公共汽车的代码。我们再次使用“传递接力棒”模式。
当公共汽车到达时,它会获取互斥量,防止迟到的人进入上客区。如果没有乘客,它马上离开。否则,它会发出bus信号,等待乘客们上车。
下面是骑手的代码:
multiplex控制等待区域内的乘客数量,但严格来说,乘客在递增riders之前不会进入等候区域。
乘客们等待bus信号,直到公共汽车到达。 当乘客们醒来时,可以理解为有互斥锁。 上车后,每个乘客都会递减riders。如果有更多乘客在等待,已上车的乘客会发出bus信号并将互斥锁传递给下一位乘客。 最后一个乘客发出allAboard信号并将互斥锁传递回公共汽车。
最后,公共汽车释放互斥锁并离开。
思考:你能用“我会为你做的”模式找到这个问题的解决方案吗?
7.4.3 巴士问题方案-2#
Grant Hutchins提出了这个解决方案,它使用比以前更少的变量,并且不涉及传递任何互斥体。以下是变量:
waiting是上客区内的乘客数量,受到互斥锁mutex的保护。 公共汽车到达时发出bus信号; 乘客上车时发出boarded信号。
下面是公共汽车的代码:
公共汽车获取互斥锁并在整个上车过程中持有它。 该循环依次向每个乘客发出信号并等待她上车。 通过控制信号的数量,公共汽车可以防止超过50名乘客上车。
当所有乘客都上车时,公交车更新waiting,这是“我会为你做的”模式的一个例子。
乘客的代码使用两种简单的模式:互斥和会合。
挑战:如果乘客在公共汽车上客时到达,你让他们等待下一辆车,他们可能会感到恼火。 您是否可以找到一种解决方案,允许延迟到达而不违反其他限制?