Является ли вариабельный своп, гарантированно быть атомным в Python?
-
26-09-2019 - |
Вопрос
Со ссылкой на следующую ссылку: http://docs.cython.org/faq/library.html#what-kinds-of-global-value-muta-are-reat-tread-safe.
Я хотел знать, если следующее:
(x, y) = (y, x)
Будет гарантирован атомным в CPYthon. (x и y - оба переменные Python)
Решение
Давайте посмотрим:
>>> x = 1
>>> y = 2
>>> def swap_xy():
... global x, y
... (x, y) = (y, x)
...
>>> dis.dis(swap_xy)
3 0 LOAD_GLOBAL 0 (y)
3 LOAD_GLOBAL 1 (x)
6 ROT_TWO
7 STORE_GLOBAL 1 (x)
10 STORE_GLOBAL 0 (y)
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
Это не появляется, что они атомные: значения X и Y могут быть изменены другим потоком между LOAD_GLOBAL
Байтекоды, до или после ROT_TWO
, и между STORE_GLOBAL
Байтекоды.
Если вы хотите поменять две переменные атомным образом, вам понадобится замок или мьютекс.
Для тех, кто желает эмпирическим доказательством:
>>> def swap_xy_repeatedly():
... while 1:
... swap_xy()
... if x == y:
... # If all swaps are atomic, there will never be a time when x == y.
... # (of course, this depends on "if x == y" being atomic, which it isn't;
... # but if "if x == y" isn't atomic, what hope have we for the more complex
... # "x, y = y, x"?)
... print 'non-atomic swap detected'
... break
...
>>> t1 = threading.Thread(target=swap_xy_repeatedly)
>>> t2 = threading.Thread(target=swap_xy_repeatedly)
>>> t1.start()
>>> t2.start()
>>> non-atomic swap detected
Другие советы
Да, да, это будет.
Kragen Citaker пишет:
Кто-то рекомендовал использовать идиому
spam, eggs = eggs, spam
чтобы получить потоковую сумму. Это действительно работает? (...)
Так что если эта нить теряет контроль в любом месте между первой Load_Fast
и последний Store_fast, значение может быть сохранено другим потоком
в «B», который тогда будет потерян. Нет ничего сохранять это
От происхождения есть?Неа. Как правило, даже не простое назначение не обязательно безопасно резьба, поскольку выполнение присвоения может вызывать специальные методы на объекте, который сами может потребовать ряд операций. Надеюсь, объект будет внутренне заблокирован своими «государственными» ценностями, но это не всегда так.
Но это действительно продиктовано тем, что «безопасность потоков» означает в конкретном применении, поскольку для моего разума есть много уровней зернистости такой безопасности, поэтому трудно говорить о «Безопасности потоков». О том, что только интерпретатор Python будет предоставить вам бесплатно, так это то, что встроенный тип данных должен быть в безопасности от внутренней коррупции даже с нативной резьбой. Другими словами, если два потока имеют
a=0xff
а такжеa=0xff00
, а завершен с одним или другим, но не случайно0xffff
Как можно возможно на некоторых других языках, если A не защищен.С этим сказал, Python также имеет тенденцию выполнять таким образом, что вы можете сойти с ужасным большим количеством без формального блокировки, если вы готовы жить на краю немного и подразумевали зависимости от реальных объектов в использовании. Отказ Здесь было приличное обсуждение вдоль этих строк здесь, в CLP A, когда обратно - поисковые группы. Google.com для «критических разделов и нити Mutexes» среди прочего.
Лично, Я явно блокирую общее состояние (или использовать конструкции, предназначенные для обмена общей информацией, правильно среди потоков, таких как
Queue.Queue
) в любом многопоточенном приложении. На мой взгляд, это лучшая защита от обслуживания и эволюции по дороге.-- -- Дэйвид