¿Los contenedores incorporados de Python son seguros para subprocesos?

Me gustaría saber si los contenedores incorporados de Python (lista, vector, conjunto …) son seguros para subprocesos? ¿O necesito implementar un entorno de locking / deslocking para mi variable compartida?

Related of "¿Los contenedores incorporados de Python son seguros para subprocesos?"

Debe implementar su propio locking para todas las variables compartidas que se modificarán en Python. No tiene que preocuparse por la lectura de las variables que no se modificarán (es decir, las lecturas simultáneas están bien), por lo que los tipos inmutables ( frozenset , tuple , str ) probablemente sean seguros, pero no duelen. Para las cosas que vas a cambiar: list , set , dict y la mayoría de los demás objetos, debes tener tu propio mecanismo de locking (mientras que las operaciones en el lugar son correctas en la mayoría de estos, los subprocesos pueden llevar a errores muy desagradables) También podrías implementar el locking, es bastante fácil.

Por cierto, no sé si lo sabes, pero el locking es muy sencillo en Python: crea un objeto threading.lock, y luego puedes adquirirlo / liberarlo así:

 import threading list1Lock = threading.Lock() with list1Lock: # change or read from the list here # continue doing other stuff (the lock is released when you leave the with block) 

En Python 2.5, haga from __future__ import with_statement ; Python 2.4 y antes no tienen esto, así que querrás poner las llamadas de adquisición () / release () en try:...finally: blocks:

 import threading list1Lock = threading.Lock() try: list1Lock.acquire() # change or read from the list here finally: list1Lock.release() # continue doing other stuff (the lock is released when you leave the with block) 

Muy buena información acerca de la sincronización de hilos en Python .

Sí, pero todavía tienes que tener cuidado, por supuesto

Por ejemplo:

Si dos subprocesos están compitiendo para pop() de una lista con solo un elemento, Un subproceso obtendrá el elemento con éxito y el otro obtendrá un IndexError

Código como este no es seguro para subprocesos

 if L: item=L.pop() # L might be empty by the time this line gets executed 

Deberías escribirlo así

 try: item=L.pop() except IndexError: # No items left 

Son seguros para subprocesos siempre y cuando no deshabilites la GIL en el código C para el subproceso.