ずいぶん前に友人とPythonのスレッドの実装の話になって
調べた時の内容が案外レアかもしれないのでメモです。
たぶんRuby1.9に実装されたYARVも大体同じような実装でしょう。
- PythonのスレッドはOSの提供するネイティブスレッドと直接対応する
- しかし、CPythonでは同時に動作するスレッドは1個のみ(
GiantGlobal Intepreter Lock) - したがって遊んでいるCPUコアがあっても1個しか使われない
- JythonやIronPythonでは複数スレッドが同時に動く
- それぞれのPythonVMの命令が実行されている間は、Pythonスレッドが切り替わらないことが保証されている
- スレッドの切り替えはsys.setcheckintervalで設定された値の数(デフォルト100)の命令が実行されるか、I/O待ち、Sleepに入った時に行われる
- このためCPythonではスレッドセーフのために同期処理を入れなくても大体動くが、不幸にもスレッド切り替えをまたいだ場合はRace Conditionが発生する可能性がある
- いままでCPythonでも同時に複数のスレッドが動くようにしてほしいという要望が何回も出ているが、拡張モジュールをスレッドセーフにすることを考えると到底無理ということで却下され続けている
ためしにPythonのスレッドを100個作ってみると、
OS上のスレッドは101個(1個はインタプリタのメインスレッド)できているのが確認できます。
Ruby1.8系だといくつスレッドを作ってもOS上のスレッドの数は変わらないのと違うところですね。
参考:
Python C/API リファレンス 8.1 スレッド状態 (thread state) とグローバルインタプリタロック (global interpreter lock)
Python 2.5.1のソースコードのWin32スレッド実装
コメント (2)
間違いに気づいたのでいくつか指摘させていただきます。
GIL は Giant Intepreter Lock ではなく Global Interpreter Lock の略です。
GIL 無しの Python 実装のアイデアが「拡張モジュールをスレッドセーフにすることを考えると到底無理ということで却下され続けている」という事実はありません。
GIL 無しの Python を実装しても結果的に GIL 有りのものよりかなり遅くなってしまい役に立たないというのが理由です。
http://www.python.org/doc/faq/library/#can-t-we-get-rid-of-the-global-interpreter-lock
投稿者: 古いエントリに失礼 | 2009年02月25日 09:39
日時: 2009年02月25日 09:39
こんな古いエントリにコメントありがとうございます!
自分で挙げた参考文献にglobalってかいてありますね。良く読んでない証拠ですね…
IronPython等でGILを取り除けたのは
パフォーマンスの問題が解決できたんでしょうか。
(GCがあるとリファレンスカウンタの変更毎にロックしなくても良いのであまり影響がないとか?)
Thread関係のベンチマークを見つけましたが結構コスト大きいんですね。
http://jessenoller.com/2009/02/01/python-threads-and-the-global-interpreter-lock/
投稿者: 山川 | 2009年02月25日 12:25
日時: 2009年02月25日 12:25