threading.Lock

うちの64bitパチコンだとpyscripterの挙動がおかしいよ。結構まえからいろいろおかしかったのでインストールし直したけどなんかダイアログ出てきて開けなくなったので(前はどうにかして開けるようにした)、めんどくさいので諦めて、Spyderで書いてます。

threading.Lockを使って排他処理をします。
スレッドはthreading.Threadというthreadを扱いやすくしたインタフェースを使って実装しています。
継承して使用します。

import time
import threading

class MyThread(threading.Thread):

    lock = threading.Lock()

    def __init__(self, name, lifetime):
        threading.Thread.__init__(self)
        self.lifetime = lifetime
        #self.name = name
    def run(self):
        while not self.lifetime <= 0:
            self.lifetime -= 1
            self.lock.acquire()
            time.sleep(0.2)
            print self.getName(), "life is " , self.lifetime
            self.lock.release()

def main():

    t1 = MyThread("t1", 5)
    t2 = MyThread("t2", 5)
    t1.start()
    t2.start()
    t1.join()
    t2.join()

if __name__ == '__main__':
    main()

このthreading.Threadを使うときは__init__とrun関数をオーバーライドして使います。それ以外はオーバーライドしたらだめです。
runメソッドは直接呼ぶのではなく、startメソッドを介して呼び出します。
joinメソッドでスレッドが終了するまで待ちます。
ちなみにこのthreading.Threadは1回しかstart()を呼び出せません。2回呼び出すと例外RuntimeErrorが発生します。
焼肉ばんばんスレッド作るにはthread.start_new_threadの方が扱いやすいかもしれません。

MyThreadのクラス変数にロックオブジェクトを入れてます。
acquire()からrelease()が呼ばれるまでは1つのスレッドでしか処理ができなくなります。
試しにこの2つをコメントして実行すると、printしている情報がごっちゃになってしまいます。
acquireとreleaseの組み合わせはwithステートメントが有効です。

with self.lock:
    time.sleep(0.2)
    print self.getName(), "life is " , self.lifetime

と書き直すことができます。
スコープから外れたら自動的にreleaseしてくれます。