最近Pythonをやりはじめていろいろコードを動かしてみた。

PythonもRubyと同様スレッド機能を持っていて、1プロセスで並列処理ができるようになっている。
PythonスレッドはOSのネイティブスレッドを使用しているみたいだが、スレッドのいいところはOSが変わってもスクリプトがちゃんと動くことだ。

ただ、複数スレッドが同じリソースをつかみにいくときに競合がおこったりデータを壊したりすることがあるので排他制御ロックを使って防ぐ。
以下はスレッドを使った数をカウントするプログラム。

import _thread as thread, time

def counter(myId, count):
    for i in range(count):
        time.sleep(1)
        mutex.acquire()
        print('[%s] => %s' % (myId,i))
        mutex.release()

mutex = thread.allocate_lock()
for i in range(5):
    thread.start_new_thread(counter, (i,5))

time.sleep(6)
print('Main thread exiting.')

1行目のimport _threadで_threadパッケージを読み込む。
10行目のthread.allocate_lock()で排他制御用のロックを取得する。
11-12行目でスレッドを5つ生成してそれぞれのスレッドでcounter関数を実行する。
counter関数の中の4行目のforループで数字をカウントしているが、6行目のmutex.acquire()で排他制御ロックを取得して他のスレッドを待たせる。
7行目のカウント数を出力したのちにmutex.release()でロックを解放する。
ロックが解放されると、他の待たされているスレッドがロックを獲得し同じ処理を実行する。
実行結果は以下のようになる。

$ python thread-counter-mutex.py
[1] => 0
[3] => 0
[0] => 0
[2] => 0
[4] => 0
[1] => 1
[3] => 1
[2] => 1
[0] => 1
[4] => 1
[1] => 2
[0] => 2
[2] => 2
[3] => 2
[4] => 2
[3] => 3
[4] => 3
[2] => 3
[1] => 3
[0] => 3
[4] => 4
[3] => 4
[2] => 4
[0] => 4
[1] => 4
Main thread exiting.