Pythonの辞書のスレッドセーフ


104

辞書を持っているクラスがあります

class OrderBook:
    orders = {'Restaurant1': None,
              'Restaurant2': None,
              'Restaurant3': None,
              'Restaurant4': None}

    @staticmethod
    def addOrder(restaurant_name, orders):
        OrderBook.orders[restaurant_name] = orders

そして、私はメソッドを呼び出す4つのスレッド(各レストランに1つ)を実行していますOrderBook.addOrder。次に、各スレッドによって実行される関数を示します。

def addOrders(restaurant_name):

    #creates orders
    ...

    OrderBook.addOrder(restaurant_name, orders)

これは安全ですか、または呼び出す前にロックを使用する必要がありますaddOrderか?


2
とにかく、各スレッドが異なるキーに書き込むときに問題が発生する可能性があります。
Jochen Ritzel、2011

63
@Jochen:ディクテーションの実装方法によっては、多くの問題が発生する可能性があります。これは非常に合理的な質問です。
Ned Batchelder、2011

回答:


94

Pythonの組み込み構造は単一の操作に対してスレッドセーフですが、ステートメントが実際に複数の操作になる場所を確認するのが難しい場合があります。

コードは安全でなければなりません。覚えておいてください。ここにロックをかけると、オーバーヘッドがほとんどなくなり、安心できます。

詳細についてはhttp://effbot.org/pyfaq/what-kinds-of-global-value-mutation-are-thread-safe.htmをご覧ください。



1
get-add-setなどの単一操作と複合操作を検討する必要があります。
アンディ14

5
問題は、私がその口述を頻繁に読み書きしているとき、心の安らぎは私に多くのコストをかけるということです。
Shihab Shahriar Khan 2017

2
「ここでロックしてもオーバーヘッドはほとんど追加されません」:なぜですか?
最大

32

はい、組み込み型は本質的にスレッドセーフです:http : //docs.python.org/glossary.html#term-global-interpreter-lock

これにより、同時アクセスに対してオブジェクトモデル(dictなどの重要な組み込み型を含む)が暗黙的に安全になるため、CPythonの実装が簡素化されます。


25
これはPythonの機能ではなく、cpythonの機能です。
phihag 2011

8
確かに、しかし私が理解しているように、JythonとIronPythonのビルトインは、GILを使用しなくてもスレッドセーフです(そして、未使用のツバメが出現しても、GILを廃止することを提案しています)。私は彼が使用しているインタプリタを指定しなかったので、彼はCPythonでそれを意味すると思いました。

1
Jythonをした場合の正しい:jython.org/jythonbook/en/1.0/...
エフゲニーSergeev

9

グーグルのスタイルガイドはdictの原子性に依存しないようにアドバイスします

:でさらに詳細に説明アトミックであるPythonの変数の割り当て?

組み込み型の原子性に依存しないでください。

ディクショナリなどのPythonの組み込みデータ型にはアトミック操作があるように見えますが、アトミックでない場合があります(例:__hash__または__eq__ Pythonメソッドとして実装されている)場合があり、そのアトミック性に依存するべきではありません。また、アトミック変数の割り当てに依存するべきではありません(これは辞書に依存するため)。

Queueスレッド間でデータをやり取りする好ましい方法として、モジュールのQueueデータ型を使用します。それ以外の場合は、スレッドモジュールとそのロックプリミティブを使用します。threading.Condition下位レベルのロックを使用する代わりに使用できるように、条件変数の適切な使用について学びます。

そして私はこれに同意します。CPythonにはすでにGILがあるため、ロックを使用した場合のパフォーマンスへの影響は無視できます。これらのCPython実装の詳細が1日に変更されると、複雑なコードベースでバグを探すのに費やす時間がはるかに高くなります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.