Pythonで排他制御を試す
threadingモジュールにセマフォがあるそうな。
LockとRLockの違い、SemaphoreとBoundedSemaphoreの違いがよくわからない。勉強不足だ。
http://docs.python.org/library/threading.html?highlight=threading#module-threading
# coding: utf-8 import threading class Plugin(threading.Thread): def __init__(self, fun): threading.Thread.__init__(self) self.fun = fun def run(self): self.fun() class ThreadGroup(object): # addメソッドに関数が渡された場合 # Pluginクラスに渡して実行 # threading.Threadの子孫クラスなら直接実行 def __init__(self): self.lst = [] def add(self, obj): if isinstance(obj, type(lambda:1)): # if obj is function obj = Plugin(obj) self.lst.append(obj) obj.start() def joinall(self): for t in self.lst: t.join() def __len__(self): return len(self.lst) class UnsafeThread(threading.Thread): # 排他制御なし counter = 0 def __init__(self, no): threading.Thread.__init__(self) self.no = no def run(self): print "unsafe",self.no for i in range(1000): UnsafeThread.counter += 1 class SafeThread(threading.Thread): # ミューテックスによる排他制御あり counter = 0 mutex = threading.Semaphore(1) def __init__(self, no): threading.Thread.__init__(self) self.no = no def run(self): SafeThread.mutex.acquire() for i in range(1000): SafeThread.counter += 1 SafeThread.mutex.release() # 4つのスレッドを走らせてjoinしたあとカウンタの値を見る。 # 4000になっているはず # unsafe g = ThreadGroup() for i in range(4): g.add(UnsafeThread(i)) g.joinall() print UnsafeThread.counter # safe g = ThreadGroup() for i in range(4): g.add(SafeThread(i)) g.joinall() print SafeThread.counter
実行結果
$ python th.py 4000 4000 $ python th.py 4000 4000 $ python th.py 3000 4000 $ python th.py 4000 4000 $ python th.py 3053 4000 $ python th.py 3318 4000 $ python th.py 4000 4000