challenge 居眠り床屋問題

並行処理のお題です。ある床屋の亭主は、客がいないときまって居眠りを始めます。床屋店内には三台の散髪兼順番待ち用の椅子があり、客は来店時に椅子に空きがあれば、いずれかに勝手に座って自分の番が来るのを待ち、散髪を終えてから店を出ます。空席が無ければそのまま何もせずに立ち去ります。居眠り中の亭主は、客の入店時に起こされると待ち客すべてをひとりずつ順に散髪しますが、誰もいなくなればまた居眠りを始めます。

この床屋店に16人の客が訪れた日のシミュレーションを行なうコードと、その結果(下に例として示したログ形式。「[スレッドのIDなど] イベント描写」の一覧と終了後の総括)を出力して示してください。なお、散髪には一人当たり100~400ミリ秒の時間(この範囲でランダムに変化)を要し、客は通常 0~200ミリ秒(同)の間隔で訪れます。ただし例外として9番目の客だけは前の客から1200ミリ秒程度の間隔(すなわち、最大三名の待ち客全員を散髪し終えるのに十分な時間)をあけて訪れるものとします。

実装に際し、実行時のデッドロックの回避はもちろんですが、そのほかにも、競合状態(席の空きを確認して座ろうとしたら、もう別の客が座っていた…というような事態)などの不整合も生じないよう配慮し、必要であればそのための対策を講じてください。たとえば来客の間隔が仮に0ミリ秒で固定の場合(つまり、客が一斉に来店した場合)でも、コードが正常に動作するかどうか試してみるのもよいかもしれません。

 

 

出力例:

[7302088] 床屋、眠る

[7012360] 来店 1

[7302088] 床屋、目覚める

[7302088] 散髪開始 1

[7012360] 来店 2

[7012360] 来店 3

[7302088] 散髪完了 1

[7302088] 散髪開始 2

[7012360] 来店 4

[7012360] 来店 5

[7012360] 満席で立ち去る 5

[7302088] 散髪完了 2

[7302088] 散髪開始 3

[7012360] 来店 6

[7012360] 来店 7

[7012360] 満席で立ち去る 7

[7012360] 来店 8

[7012360] 満席で立ち去る 8

[7302088] 散髪完了 3

[7302088] 散髪開始 4

[7302088] 散髪完了 4

[7302088] 散髪開始 6

[7302088] 散髪完了 6

[7302088] 床屋、眠る

[7012360] 来店 9

[7302088] 床屋、目覚める

[7302088] 散髪開始 9

[7012360] 来店 10

[7012360] 来店 11

[7012360] 来店 12

[7012360] 満席で立ち去る 12

[7302088] 散髪完了 9

[7302088] 散髪開始 10

[7012360] 来店 13

[7012360] 来店 14

[7012360] 満席で立ち去る 14

[7012360] 来店 15

[7012360] 満席で立ち去る 15

[7302088] 散髪完了 10

[7302088] 散髪開始 11

[7012360] 来店 16

[7302088] 散髪完了 11

[7302088] 散髪開始 13

[7302088] 散髪完了 13

[7302088] 散髪開始 16

[7302088] 散髪完了 16

[7302088] 床屋、眠る

※ 16人のうち 10人を散髪

 

Posted feedbacks

Number of comments:19 Nested Flatten
  1. 4 Common Lisp
  2. 2 C C# Java
  3. 1 Groovy JavaScript Scala Python Ruby Smalltalk Perl

Index

Feed

Other

Link

Pathtraq

loading...