¿Las variables de instancia de Python son seguras para subprocesos?

OK, revisa los siguientes códigos primero:

class DemoClass(): def __init__(self): #### I really want to know if self.Counter is thread-safe. self.Counter = 0 def Increase(self): self.Counter = self.Counter + 1 def Decrease(self): self.Counter = self.Counter - 1 def DoThis(self): while True: Do something if A happens: self.Increase() else: self.Decrease() time.sleep(randomSecs) def DoThat(self): while True: Do other things if B happens: self.Increase() else: self.Decrease() time.sleep(randomSecs) def ThreadSafeOrNot(self): InterestingThreadA = threading.Thread(target = self.DoThis, args = ()) InterestingThreadA.start() InterestingThreadB = threading.Thread(target = self.DoThat, args = ()) InterestingThreadB.start() 

Estoy enfrentando la misma situación que arriba. Realmente quiero saber si es seguro para self.Counter para self.Counter . self.Counter , bueno, si no, ¿qué opciones tengo? Solo puedo pensar en threading.RLock() para bloquear este recurso, ¿alguna idea mejor?

Puede usar Bloqueos, Bloqueos, Semáforos, Condiciones, Eventos y Colas.
Y este artículo me ayudó mucho .
Échale un vistazo: el blog de Laurent Luce

El uso del campo de instancia self.Counter es seguro para subprocesos o “atómico” . Al leerlo o asignarle un solo valor, incluso cuando necesita 4 bytes en la memoria, nunca obtendrá un valor a medio cambiar. Pero la operación self.Counter = self.Counter + 1 no se debe a que lee el valor y luego lo escribe; otro hilo podría cambiar el valor del campo después de haberlo leído y antes de que se vuelva a escribir.

Así que necesitas proteger toda la operación con un candado.

Como el cuerpo del método es básicamente la operación completa, puedes usar un decorador para hacer esto. Vea esta respuesta para ver un ejemplo: https://stackoverflow.com/a/490090/34088

No, no es seguro para subprocesos: los dos subprocesos esencialmente modifican la misma variable simultáneamente. Y sí, la solución es uno de los mecanismos de locking en el módulo de threading .

Por cierto, self.Counter es una variable de instancia , no una variable de clase .

self.Counter es una variable de instancia por lo que cada hilo tiene copia. Si declara la variable fuera de __init () será una variable de clase. Todas las instancias de la clase compartirán esa instancia.