a,b=1,2
のような操作はアトミックですか?1ステップがPythonの原子操作かどうかを確認する方法
私の問題の背景:私は信号で作業しています。いくつかの外部プロセスから提起されている。ここでは、信号がa=1 and b=2
の間にキャプチャされている場合を避けたいと思います。これを達成する方法はありますか?
与えられたステップがアトミックかどうかを確認する方法はありますか?
a,b=1,2
のような操作はアトミックですか?1ステップがPythonの原子操作かどうかを確認する方法
私の問題の背景:私は信号で作業しています。いくつかの外部プロセスから提起されている。ここでは、信号がa=1 and b=2
の間にキャプチャされている場合を避けたいと思います。これを達成する方法はありますか?
与えられたステップがアトミックかどうかを確認する方法はありますか?
それは複数の名前を割り当てるために、複数のバイトコード命令を受け取り、それを実験的にそれを確認するために時間はかかりませんので、それはアトミックではありません。この特定のケースで
import signal
a = 1
b = 2
def handler(sig, trace):
print a, b
def main():
global a, b
signal.signal(signal.SIGINT, handler)
while True:
a, b = 3, 4
a, b = 1, 2
if __name__ == '__main__':
main()
$ python atom.py
^C3 4
^C3 4
^C1 2
^C1 2
^C3 4
^C1 2
^C1 2
^C1 2
^C1 2
^C1 4 <<<< inconsistent state
、あなたは二つの値を変更したい場合原子的には、タプルへの代入やシグナルハンドラ内の要素へのアクセスを避けることができます。解体を見ていない:
>>> a = 1
>>> b = 2
>>> c = (1, 2)
>>> def foo():
... global a, b
... a, b = 1, 2
...
>>> def bar():
... global c
... c = (1, 2)
...
>>> dis.dis(foo)
3 0 LOAD_CONST 3 ((1, 2))
3 UNPACK_SEQUENCE 2
6 STORE_GLOBAL 0 (a)
9 STORE_GLOBAL 1 (b)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
>>> dis.dis(bar)
3 0 LOAD_CONST 3 ((1, 2))
3 STORE_GLOBAL 0 (c)
6 LOAD_CONST 0 (None)
9 RETURN_VALUE
をどんなに価値がどのように複雑で、変数(またはdict
エントリ、またはオブジェクトフィールド)への割り当ては、単一のアトミックストア操作です。
これはまさに私がチェックしたかったものです。 – gsagrawal
私はこの答えが素晴らしいと思います。将来の参照や訪問者のために、誰か(あなた?:-))は時間をかけて、この矛盾した状態につながるシーンの裏側で何が起こっているのかを詳細に説明する必要があります(STORE_FAST ) 'は' STORE_FAST(b) 'の前に実行されます)。 –
いいえ、シーケンス割り当てはアトミックではありません。
>>> def unpack():
a,b=1,2
>>> import dis
>>> dis.dis(unpack)
2 0 LOAD_CONST 3 ((1, 2))
3 UNPACK_SEQUENCE 2
6 STORE_FAST 0 (a)
9 STORE_FAST 1 (b)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
タプルを評価してその結果を変数に格納するには、複数のオペコードが必要です。
この手順は6個の原子操作を含んでいますか?またはこれは2アトミック操作です。 – gsagrawal
1つのオペコード命令はアトミックです。異なるスレッドは、任意の2つのオペコードの間でいつでも考慮して値を変更できます。 –
も参照してください:http://stackoverflow.com/questions/2623086/is-a-variable-swap-guaranteed-to-be-atomic-in-python – nemo