キーが辞書にあるかどうかをチェックしていますif key in mydict
- アトミック操作ですか?
そうでない場合、別のスレッドが辞書を変更している間にスレッドがキーをチェックしていた場合、悪影響はありますか? チェック スレッドはディクショナリを変更しません。キーの存在に応じて異なる動作をするだけです。
キーが辞書にあるかどうかをチェックしていますif key in mydict
- アトミック操作ですか?
そうでない場合、別のスレッドが辞書を変更している間にスレッドがキーをチェックしていた場合、悪影響はありますか? チェック スレッドはディクショナリを変更しません。キーの存在に応じて異なる動作をするだけです。
「アトミック」は本当にあなたが興味を持っているものではないと思います。
CPythonを使用していない場合(または使用しているが、スレッドの1つがGILの下にないCコードを実行している場合…)、それは間違いなくアトミックではありませんが、特定の条件下ではとにかく安全かもしれません。
CPythonを使用している場合、それin
は単一のバイトコードop(COMPARE_OP 6
)であるという意味でアトミックであり、実際のハッシュテーブルルックアップ自体は確実にGILの下で行われ、潜在的な同等性の比較は確実に生きていることが保証されているオブジェクト。ただし、特定の条件下を除いて、それでも安全ではない可能性があります。
まず、ここで実行している高レベルの操作は本質的に際どいものです。スレッド1が実行できる場合、d['foo'] = 3
またはdel d['foo']
同時にスレッド0が呼び出している'foo' in d
場合、正しい答えはありません。アトミックかどうかの問題ではありません。ここにはシーケンスはありません。
ただし、アプリケーションレベルで何らかの明示的なシーケンス処理を行っている場合、正しい答えが得られる場合は、両方のスレッドがGILを保持している場合にのみ正しい答えが得られることが保証されます。それがあなたが求めていることだと思いますね
これはCPythonでのみ可能です。そして、それでも、これまでに入れたオブジェクトがdict
GILを解放しようとしたときに、それを解放できないhash
こと==
を保証することになります。これは、一般的に保証するのは難しいことです。
では、他のスレッドがキーのセットを変更せずに、キーに関連付けられた値を置き換えるだけの場合はどうなるでしょうか。次に、正しい答えがありdict
、実装がこの操作のハッシュテーブルの変更を回避する限り、同時に利用できます。少なくとも、2010年7月29日までにリリースされたものまでのCPythonのバージョンでは。Alex Martelliは、Python辞書への回答でスレッドセーフであることを間接的に保証していますか?。したがって、その制限されたケースでは、CPythonで安全であり、他の実装でも安全ですが、それに依存する前にコードを読みたいと思うでしょう。
コメントで指摘されているように、ルックアップ値と比較する可能性のあるキーは不変であることが保証されていないため、他のスレッドがキーのセットを変更することを何もしなくても、それが完全に保証されるわけではありません。あなたは正しい答えを得るでしょう。(これを失敗させるには、病理学的キータイプを作成する必要があるかもしれませんが、それでも正当なキータイプです。)