操作はa,b=1,2
アトミックのようなものですか?
私の問題の背景:私は signal を扱っています。これは、何らかの外部プロセスから発生しています。ここで、設定の間に信号がキャプチャされるケースを避けたいと思いますa=1 and b=2
。これを達成する方法はありますか?
特定のステップがアトミックかどうかを確認する方法はありますか?
操作はa,b=1,2
アトミックのようなものですか?
私の問題の背景:私は signal を扱っています。これは、何らかの外部プロセスから発生しています。ここで、設定の間に信号がキャプチャされるケースを避けたいと思います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
この特定のケースで、2 つの値をアトミックに変更したい場合は、タプルへの代入とシグナル ハンドラーでの要素へのアクセスを回避できます。分解を見る:
>>> 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
エントリ、またはオブジェクト フィールド) への割り当ては、単一のアトミック ストア操作です。
いいえ、シーケンスの割り当てはアトミックではありません。バイトコードを見てください:
>>> 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
割り当ては、タプルを評価し、結果を変数に格納するために複数のオペコードを取ります。