pythonのthread/threadingモジュールを見てみた
Blog: threadの動作の違うよ。 - Humming Via Kitchen を見てちょっと気になった のでPythonのコードを見てみた。(via 常山日記 )
threadモジュールを使ったサンプルは、簡単に書くとこんな感じのコード。
import thread def run(): # do something def main(): thread.start_new_thread(run, ())
pthread_join()に相当する関数を呼んでないからmain()関数が終了しちゃったら実行途中 のthreadも終了させられちゃってるんじゃない?と思ってthreadモジュールのマニュアル を見ると、なんとjoin()に相当する関数ないんだね。 どうやってスレッドの終了時の同期をとるんだ?そもそもPythonのソースコードを検索し てもpthread_join()はどこでも呼ばれていない。pthread_detach()が呼ばれているので pthreadレベルで終了時の同期を取る手段は用意されていないようだ。
ということで、main()関数が終了した場合には実行途中のスレッドが終了させられるのは 仕方がないね。
一方、threadingモジュールを使うとthreadモジュールと同様にjoin()に相当する関数を 呼んでないけど、main()関数終了後もスレッドが動作し続ける。
threadingモジュールを使ったサンプルは、簡単に書くとこんなコード。
from threading import Thread
class TestThread(Thread):
def run(self):
# do something
def main():
TestThread().start()
ちなみにマニュアルを見るとthreadingモジュールにはjoin()メソッドが存在する。上で書い たようにPythonソース内にpthread_join()は存在しないのでpthread_join()は使ってない 。threadingモジュール内で実現している。
でも、ここではjoin()メソッドは呼んでない。呼んでないけどあたかも呼んでるかのよう に動作している。
どうなってるんだ?ということでソースを見てみる。python2.4と2.5で実現方法が異なった。
まずはpython2.4。
threadingモジュール内でatexitモジュールを呼びだし、Pythonインタープリタの終了 処理にjoin()メソッドを登録している。
次にpython2.5。
Pythonインタープリタのメイン関数Py_Main()内でインタープリタが終了する際に呼び 出されるPy_Finalize()直前にWaitForThreadShutdown()という関数が追加され、ここで threading._shutdown()が呼ばれ、threading._shutdown()内でjoin()メソッドが呼ばれる。
という方法でそれぞれ実現していました。
おかげで勉強になりました。Pythonのソース見るのもなかなかおもしろいね。threadモジ ュールよりはthreadingモジュールを使った方が良さそうかな、と思いました。

