-1

Locking でアトミック カウンターを使用する必要がありますか、それともこれを使用できますか?

 def somefunc(someparam):
     if someparam:
        dic['key'] +=1
4

2 に答える 2

3

いいえ、あなたのコードはスレッドセーフではありません。+=ディクショナリ値で拡張割り当てを使用すると、実行に 3 つのオペコードが必要になるためです。

>>> dis.dis(compile("dic['key'] += 1", '', 'exec'))
  1           0 LOAD_NAME                0 (dic)
              3 LOAD_CONST               0 ('key')
              6 DUP_TOPX                 2
              9 BINARY_SUBSCR
             10 LOAD_CONST               1 (1)
             13 INPLACE_ADD
             14 ROT_THREE
             15 STORE_SUBSCR
             16 LOAD_CONST               2 (None)
             19 RETURN_VALUE

位置 9 のオペコードはBINARY_SUBSCR、ディクショナリから現在の値を取得します。STORE_SUBSCRオペコード 9 と 15 の間 (値を戻す場所) のどこでも、スレッド切り替えが発生し、別のスレッドが辞書を更新した可能性があります。

于 2016-11-14T16:56:40.437 に答える
1

Python の組み込み構造は、単一操作に対してスレッド セーフです。GIL (グローバル インタープリター ロック) がそれを処理します。しかし、ステートメントがより多くの操作になる場所を確認することはほとんどの場合困難です。

ロックを追加すると安心できます。

def somefunc(someparam):
    if someparam:
        with lock:
            dic['key'] +=1
于 2016-11-14T17:00:49.663 に答える