マルチスレッド環境で動作するプログラムでは、同じデータが同時に更新されないように制御するのが、とても大きな問題です。複数のスレッドで同時に辞書やリストなどにデータの更新が発生した場合、データ構造が破壊されてしまう場合があるためです。こういった障害は、データ競合 と言います。
GILを持たないJavaなどのプログラミング言語では、データ競合が発生しないように制御するのはプログラマの責任です。しかし、マルチスレッド環境で正しく動作するプログラムの開発はとても難しく、一つ間違えればパフォーマンスの低下やロック漏れ・デッドロック など、解決の難しい、とても恐ろしい問題が発生します。
システムプログラミング言語のJavaでは、最大の自由度とパフォーマンスを得るために、プログラマが苦労してマルチスレッド用のロジックを開発するようになっています。しかし、スクリプト言語で専門家ではないユーザも利用するPythonでは、データ競合の解決を利用者にまかせるのではなく、主要な用途では競合が発生しないように、GILを使って並列的に実行できないようにしています。
GILの除去¶
しかし、そうは言ってもやはり並列実行は魅力的です。現在のCPythonでは常にCPUを一つしか使えないため、現代の優れたハードウェアを活かすことができません。昔からGILの手軽さを保ったまま、並列実行を可能にする試みは行われていましたが、互換性とパフォーマンスを兼ね備えた成果は得られませんでした。Greg Stein氏が1996年に開発したフリースレッドなPython1.4などが有名ですが、パフォーマンスの低下が著しく、実用はされませんでした。
Pythonは実行中に多くの管理用データを更新・参照します。GIL環境下ではいちどGILを確保すれば、データ競合を避けるために他のロックを取得する必要はありません。しかし、GILがなければ、管理データにアクセスするごとにそれぞれのデータについてロックを取得・開放する必要があります。このため、GILを削除すればパフォーマンスの低下は避けられず、フリースレッドPythonの実現は困難であるとされていました。
今回、 PEP-703の提案では、プログラマの負荷を最小限にとどめ、GIL除去によるパフォーマンス低下を最低限にするために多くの手法が提案されています。初期の実装では、シングルスレッドな処理は通常のCPythonと同等のパフォーマンスを維持した上で、20スレッドの同時実行でシングルスレッドの20倍近くの速度が得られたと報告されています。以下に、提案されている主な手法を紹介します。