> Chutaさん他
予定は空けてあったので、どっかで適当になんかやるのもありかなーと思いつつ
会場を確保するのも面倒だし・・・どうしますかね。
ネカフェでも使ってハッカソン風に適当にやるとかでも企画しますか?
というわけで、参加希望者があと2人いれば、ネカフェで緩めのオフ会でもやりましょう。
ネタはDjangoで、内容はなんか作ってみるとかそんな方向で。
金曜日は台風ということですが、お昼くらいに集まって
13時からアイカフェでということで如何でしょう?
http://www.i-cafe.ne.jp/norbesa/static/admission.php
だいたい6-7人くらいまでは入れるので適当に。
※参加費は実費でだいたい1500~2000円程度です。
む、10時までに入れば半額・・・だと?
集合は13:00にノルベサの方のアイカフェということで。
入店してから飯食ってもいいですし、食ってから来てもどちらでもOK。
6人くらいまで問題なく入れるんで、適当に飛び入りでご参加ください。
適当に雑談しながらDjangoでも触ろうかと思いますが、予定は未定ですw
私は Python でも使える IDE のセットアップと、下に示した並行処理
のシンプルな問題を解いていました。成果発表を兼ねて、問題と
コードをお送りします。Python 使いの皆様には、添削などお願い
できれば幸いです。
なおお題のほうは、このまま どう書く?orgで出題してみる予定です。
==
居眠り床屋問題
並行処理のお題です。ある床屋の亭主は、客がいないときまって居眠りを始めます。床屋店内には三台の散髪兼順番待ち用の椅子があり、客は来店時に椅子に空きがあれば、いずれかに勝手に座って自分の番が来るのを待ち、散髪を終えてから店を出ます。空席が無ければそのまま何もせずに立ち去ります。居眠り中の亭主は、客の入店時に起こされると待ち客すべてをひとりずつ順に散髪しますが、誰もいなくなればまた居眠りを始めます。
この床屋店に16人の客が訪れた日のシミュレーションを行なうコードと、その結果(下に例として示したログ形式。「[スレッドのIDなど]
イベント描写」の一覧と総括)を出力して示してください。なお、散髪には一人当たり100~400ミリ秒の時間(ランダムに変化)を要し、客は通常
0~200ミリ秒(同)の間隔で訪れます。ただし例外として9番目の客だけは前の客から1000ミリ秒程度の間隔(すなわち、最大三名の待ち客全員を散髪し終えるのに十分な時間)をあけて訪れるものとします。
実装に際し、実行時のデッドロックの回避はもちろんですが、そのほかにも、競合状態(席の空きを確認して座ろうとしたら、もう別の客が座っていた…というような事態)などの不整合も生じないよう配慮し、必要であればそのための対策を講じてください。たとえば来客の間隔が仮に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人を散髪
参考: Wikipedia - Sleeping barber problem
http://en.wikipedia.org/wiki/Sleeping_barber_problem
$ cat sleepingbarber.py
# coding:utf-8
from threading import *
import thread
from time import sleep
import random
queue = list()
lock = Lock()
keep_running = True
next_customer = None
event = Event()
tally = 0
def barber():
global next_customer
global tally
while keep_running:
if next_customer:
id = next_customer
print u"[%i] 散髪開始 %s".encode('utf-8') %(thread.get_ident(), id)
sleep(random.randint(100,400) / 1000.0)
print u"[%i] 散髪完了 %s ".encode('utf-8') %(thread.get_ident(), id)
lock.acquire()
queue.pop(0)
next_customer = None
lock.release()
tally += 1
if len(queue) == 0:
print u"[%i] 床屋、眠る".encode('utf-8') %thread.get_ident()
event.wait()
if next_customer: print u"[%i] 床屋、目覚める".encode('utf-8')
%thread.get_ident()
def shop():
global next_customer
while keep_running:
lock.acquire()
if not next_customer and len(queue) > 0:
next_customer = queue[0]
event.set()
event.clear()
lock.release()
Thread(target=barber).start()
Thread(target=shop).start()
num_of_customer = 16
for id in xrange(1,num_of_customer+1):
sleep(random.randint(0,200) / 1000.0)
lock.acquire()
print u"[%i] 来店 %s".encode('utf-8') %(thread.get_ident(), id)
if len(queue) < 3:
queue.append(id)
else:
print u"[%i] 満席で立ち去る %s".encode('utf-8') %(thread.get_ident(), id)
lock.release()
if id == num_of_customer // 2: sleep(1)
sleep(2)
event.set()
keep_running = False
print u"※ %s人のうち %s人を散髪".encode('utf-8') %(num_of_customer, tally)