0

処理スレッドと監視スレッドがあるコードがあります。処理スレッドでは、collections.deque.popleft 関数を呼び出しています。popleft関数で処理関数がブロックされている場合でもモニタースレッドを実行したいので、この関数がGILを解放するかどうかを知りたかった

4

2 に答える 2

1

この特定の質問に答える代わりに、別の質問に答えます。

Global Interpreter Lock (GIL)とは何ですか? プログラムをブロックするのはいつですか?

つまり、GIL はインタープリターの状態が同時スレッドによって破損するのを防ぎます。

の目的を理解するために、 の低レベルの実装を考えてみましょう。この実装にはdict、どこかにキーの配列があり、すばやく検索できるように編成されています。次のようなコードを書く場合:

myDict['foo'] = 'bar'

Python インタープリターは、キーのコレクションを調整する必要があります。これには、追加のキー用のスペースを空けることや、特定のキーをその配列に追加することが含まれる場合があります。

複数の同時スレッドがその dict を変更している場合、1 つのスレッドが配列を再割り当てし、別のスレッドが配列を変更している間に、予期しない、おそらく悪い動作 (破損したデータ、セグメンテーション違反、またはメモリ コンテンツ リークのようなハートブリードによるもの) を引き起こす可能性があります。機密データまたは任意のコードの実行)

これは、Python アプリケーションのレベルで合理的に記述または防止できるような状態ではないため、ランタイムは、この種の問題が発生するのを防ぐために多大な時間を費やします。その方法は、dict の変更など、インタプリタの特定の部分がPyGILState_Ensure()/PyGILState_Release()ペアで囲まれているため、重要な操作は常に一貫した状態になります。

ただし、このロックの範囲は非常に狭いことに注意してください。collections.deque一般的なデータ競合から保護しようとはしません。複数のスレッドが共通のコンテナー (たとえば、 a ) で互いの作業を上書きするプログラムを作成することから保護しません。そのようなプログラムを作成したとしても、インタープリターがクラッシュすることはありません。常に有効で機能するdeque. queue.Queueアプリケーションに優れた同時実行セマンティクスを与えるために、追加のアプリケーション ロックを追加できます。

GIL が保護するすべての操作はインタープリター状態の変更であるため、外部イベントでブロックされることはありません。これらのイベントによってインタプリタの状態が変更されることはないため、シグナリング条件変数によってメモリが破損することはありません。


問題が発生する可能性があるのは、ブロックされていないスレッドがいくつかある場合のみです。それらはすべて低レベルのインタープリターでコードを実行している可能性があり、GIL をめぐって競合し、1 つのスレッドだけがそれを保持でき、他のスレッドもブロックします。計算をしたい。

C 拡張機能を作成していない限り、おそらく心配する必要はありません。また、 python で複数の計算バインド スレッドを使用していない限り、その影響も受けません。

于 2014-06-04T00:54:57.873 に答える