排他処理もやって見る

from threading import Thread, Semaphore, Lock
import time
semaphore = Semaphore(1)
lock = Lock()
〜〜中略〜〜
    def run(self):
        self.n = 1
        while True:
            self.Pause()
            print self.name,self.n
            time.sleep(1)
            self.n += 1

    def Pause(self):
        #semaphore.acquire()
        lock.acquire()
        if self.n % 5 == 0:
            for i in xrange(3):
                time.sleep(1)
                print self.name, "PAUSE"
        #semaphore.release()
        lock.release()
〜〜以下略〜〜

実行してみると、見事にpause中は片方のスレッドの処理が止まっている

test1 1
test1 2
test2       1
test1 3
test2       2
test1 4
test2       3
test1 PAUSE
test1 PAUSE
test1 PAUSE
test1 5
test2       4
test1 6
test2       PAUSE
test2       PAUSE
test2       PAUSE
test2       5
test1 7
test2       6
test1 8
test2       7
test1 9
test2       8
test1 PAUSE
test1 PAUSE

排他処理にはSemaphoreとLockの2種類がるが、違いは不明。Semaphoreの場合はSemaphore(1)とかSemaphore(2)とかやって、制限数を変更できる(デフォルトは1)。
あと上の例だと表示がちょっと変わる。Lock()を使うと、

test1 1
test1 2
test1 3
test2       1
test1 4
test2       2
test1 PAUSE
test1 PAUSE
test1 PAUSE
test1 5 test2       3

test2       4

なんか変。

因みに以下のようにSemaphore、Lockをコンストラクタで指定すると、排他処理は機能しない。

class threadtest(Thread):
    def __init__(self,name):
        Thread.__init__(self)
        self.semaphore = Semaphore(1)
        self.lock = Lock()
〜〜〜〜〜〜〜〜実行〜〜〜〜〜〜〜〜
test1 1
test1 2
test1 3
test2       1
test1 4
test2       2
test2       3
test1 PAUSE
test2       4
test1 PAUSE
test1 PAUSE

けれど、メンバ変数的に使うと、うまくいく。例えば下だと機能する。これは意味不明。

class threadtest(Thread):
    self.semaphore = Semaphore(1)
    self.lock = Lock()
    def __init__(self,name):
〜〜以下略〜〜