注: 私が言及thread
するところはどこでも、私は特にPythonのスレッドを意味します、明示的に述べるまでます。
あなたがから来ている場合、スレッドはPythonで少し異なって動作します C/C++
バックグラウンドいる。Pythonでは、一度に1つのスレッドのみが実行状態になります。つまり、Pythonのスレッドは、設計上、複数のコアで並列に実行することができないため、複数の処理コアの能力を実際に活用することはできません。
Pythonのメモリ管理はスレッドセーフではないため、各スレッドはPythonインタープリターのデータ構造への排他的アクセスを必要とします。この排他的アクセスは(グローバルインタープリターロック)と呼ばれるメカニズムによって取得されます。GIL
Why does python use GIL?
複数のスレッドがインタプリタの状態に同時にアクセスしてインタプリタの状態を破壊するのを防ぐため。
アイデアは、スレッドが実行されているときはいつでも(メインスレッドであっても)、GILが取得され、事前定義された時間の後に、GILが現在のスレッドによって解放され、他のスレッド(存在する場合)によって再取得されます。
Why not simply remove GIL?
GILを削除することは不可能ではありません。削除することで、アクセスをシリアル化するためにインタープリター内に複数のロックを配置することになり、単一のスレッドアプリケーションでもパフォーマンスが低下します。
したがって、GILを削除するコストは、シングルスレッドアプリケーションのパフォーマンスの低下によって支払われますが、これは決して望ましくありません。
So when does thread switching occurs in python?
スレッド切り替えはGILがリリースされると発生しますが、GILはいつリリースされますか?考慮すべき2つのシナリオがあります。
スレッドがCPUバウンド操作(画像処理など)を実行している場合。
古いバージョンのpythonでは、スレッドの切り替えはpython命令の固定数の後に発生100
していました。デフォルトではに設定されていました。単一の命令の実行に時間がかかったため、切り替えをいつ実行するかを決定するのはあまり適切なポリシーではないことが判明しました。ミリ秒から1秒まで非常に乱暴になります。したがって、毎回GILをリリースします。100
に発生する可能性があるため、実行にかかる時間に関係なく、命令のすることは不適切なポリシーです。
新しいバージョンでは、スレッドを切り替えるためのメトリックとして命令カウントを使用する代わりに、構成可能な時間間隔が使用されます。デフォルトの切り替え間隔は5ミリ秒sys.getswitchinterval()
です。を使用して、現在の切り替え間隔を取得できます。これは、を使用して変更できますsys.setswitchinterval()
スレッドがIOバウンド操作を実行している場合(ファイルシステムアクセスまたは
ネットワークIOなど)
GILは、スレッドがIO操作の完了を待機しているときはいつでも解放されます。
Which thread to switch to next?
インタプリタには独自のスケジューラがありません。間隔の終わりにどのスレッドがスケジュールされるかは、オペレーティングシステムの決定です。。