私の理解では、cPython のグローバル インタープリター ロックにより、一度に実行できるスレッドは 1 つだけです。これは、失われた更新の問題などの競合状態から自動的に保護されますか?
明確にするために、私は理論的な観点から尋ねています。同期なしでスレッド化されたコードを書くことは決してありません。
私の理解では、cPython のグローバル インタープリター ロックにより、一度に実行できるスレッドは 1 つだけです。これは、失われた更新の問題などの競合状態から自動的に保護されますか?
明確にするために、私は理論的な観点から尋ねています。同期なしでスレッド化されたコードを書くことは決してありません。
GIL により、Python バイトコードを実行するためにアクティブなプロセスごとのスレッドは常に 1 つだけです。バイトコード評価ループはそれによって保護されます。
ロックは毎秒解放されsys.getswitchinterval()
、その時点でスレッドの切り替えが行われます。つまり、Pythonコードの場合、スレッドの切り替えは引き続き実行できますが、バイト コード命令間でのみ実行できます。スレッド セーフに依存するコードでは、これを考慮する必要があります。1 つのバイトコードで実行できるアクションはスレッド セーフにできますが、それ以外はすべてそうではありません。
1 バイト コードの命令でも、他の Python コードをトリガーできます。たとえば、この行は、Python で実装されたカスタム クラスobject[index]
の呼び出しをトリガーできます。__getitem__
したがってBINARY_SUBSCR
、オブジェクト タイプによっては、1 つのオペコードが必ずしもスレッド セーフであるとは限りません。