¿Se garantiza que un swap variable sea atómico en python?


Con referencia al siguiente enlace: http://docs.python.org/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe

Quería saber si lo siguiente:

(x, y) = (y, x)

Estará garantizado atómico en CPython. (x e y son ambas variables de python)

Author: dhruvbird, 2010-04-12

2 answers

Veamos:

>>> 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    

No parece que sean atómicos: los valores de x e y podrían cambiarse por otro hilo entre los bytecodes LOAD_GLOBAL, antes o después de los ROT_TWO, y entre los bytecodes STORE_GLOBAL.

Si desea intercambiar dos variables atómicamente, necesitará un bloqueo o un mutex.

Para aquellos que desean una prueba empírica:

>>> 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
 54
Author: jemfinch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-12 15:57:08

Sí, sí lo hará.

Acepto la corrección.

Kragen Sitaker escribe:

Alguien recomendó usar el modismo

spam, eggs = eggs, spam

Para obtener un intercambio seguro de hilo. ¿Esto realmente funciona? (...)
Así que si este hilo pierde el control en cualquier lugar entre el primer LOAD_FAST
y el último STORE_FAST, un valor podría ser almacenado por otro hilo
en " b " que luego se perdería. No hay nada mantener esto
de suceder, ¿verdad?

No. En general, ni siquiera un simple la asignación es necesariamente segura para subprocesos dado que la realización de la asignación puede invocar métodos especiales en un objeto que a su vez pueden requerir un número de operaciones. Esperemos que el objeto habrá encerrado internamente su valores de" estado", pero eso no siempre caso.

Pero es realmente dictado por lo que "seguridad del hilo" significa en un particular aplicación, porque a mi mente hay son muchos los niveles de granularidad de tales seguridad por lo que es difícil hablar de "thread safety" (en inglés). Acerca de la única cosa el intérprete de Python va a darle de forma gratuita es que un built-in el tipo de datos debe estar a salvo de corrupción incluso con hilos nativos. En otras palabras, si dos hilos a=0xff y a=0xff00, a terminará con uno u otro, pero no accidentalmente 0xffff como podría ser posible en algunos otros idiomas si un no protegida.

Dicho esto, Python también tiende a ejecutar de tal manera que usted puede salirse con la suya con un montón sin bloqueo formal, si estás dispuesto a vivir en el borde un poco y tener dependencias implícitas sobre la objetos en uso . Había un decente discusión sobre estas líneas aquí en c. l. p a tiempo atrás-búsqueda groups.google.com para la "Crítica secciones y mutexes " hilo entre otros.

Personalmente, I bloquear explícitamente compartido estado (o utilizar construcciones diseñadas para intercambio adecuado de información compartida entre hilos, como Queue.Queue) en cualquier aplicación multihilo. A mi mente es la mejor protección contra el mantenimiento y la evolución hacia abajo carretera.

-- -- David

 4
Author: Esteban Küber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-12 15:28:51