Python 辞書があり、複数のスレッドが追加されている場合、すべてのスレッドが独自のキーに追加されることがわかっている場合、要素の追加を同期する必要がありますか? (私が言いたいのは、同じキーを同時に追加することはできないということです)。
1 に答える
キーがスレッドごとに一意でない場合、ディクショナリ オブジェクトへのアクセスを同期する必要がある場合があります。アクセスは必ずしもスレッドセーフではありません。
dis
(逆アセンブラー) モジュールをいつでも使用して、Python コードを検証できます。Python スレッド コンテキストは、任意のオペコード間で切り替えることができます (オペコード自体はアトミックに実行されます)。dict へのアクセスは、いくつかのオペコードに分散できます。
>>> def foo():
... somedict = {}
... somedict['bar'] = 'spam'
...
>>> import dis
>>> dis.dis(foo)
2 0 BUILD_MAP 0
3 STORE_FAST 0 (somedict)
3 6 LOAD_CONST 1 ('spam')
9 LOAD_FAST 0 (somedict)
12 LOAD_CONST 2 ('bar')
15 STORE_SUBSCR
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
somedict['bar'] = spam
この行には、somedict
参照のロード、'bar'
および'spam'
定数のロード、ストア操作の呼び出しという4 つのオペコードが関係しています。スレッド コンテキストは、これらのオペコード間で切り替えることができます。
とはいえ、キーがスレッドごとに一意であることが保証されている場合は、構造をロックしなくても済む可能性があります。すべてのオペコードと同様に、STORE_SUBSCR
オペコードは GIL の下で Python インタープリターによって実行されるため、複数のスレッドが独自のキーに情報を格納したり、そこから情報を読み取ったりしても安全です。
Python 標準ライブラリ ライブラリは、いくつかの場所でこれを行います。thread.thread_ident()
スレッドごとの情報をディクショナリに格納するためのディクショナリ キーとして使用します。たとえば、モジュールは、スレッド識別子をキーにしたモジュールグローバル辞書を保持しthreading
ます_active
。