inside - python multiple global variables
Variable global de Python con hilo (2)
¿Cómo comparto una variable global con hilo?
El ejemplo de mi código Python es:
from threading import Thread
import time
a = 0 #global variable
def thread1(threadname):
#read variable "a" modify by thread 2
def thread2(threadname):
while 1:
a += 1
time.sleep(1)
thread1 = Thread( target=thread1, args=("Thread-1", ) )
thread2 = Thread( target=thread2, args=("Thread-2", ) )
thread1.join()
thread2.join()
No sé cómo hacer que los dos hilos compartan una variable.
En una función:
a += 1
será interpretado por el compilador como assign to a => Create local variable a
, que no es lo que quieres. Probablemente fallará con un error a a not initialized
ya que el (local) a no se ha inicializado:
>>> a = 1
>>> def f():
... a += 1
...
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
UnboundLocalError: local variable ''a'' referenced before assignment
Puede obtener lo que quiere con la palabra clave global
(muy mal visto, y por buenas razones), como sigue:
>>> def f():
... global a
... a += 1
...
>>> a
1
>>> f()
>>> a
2
Sin embargo, en general, debe evitar el uso de variables globales que se vuelven extremadamente rápidas. Y esto es especialmente cierto para los programas multiproceso, donde no tiene ningún mecanismo de sincronización para su thread1
para saber cuándo se ha modificado a. En resumen: los hilos son complicados y no puede esperar tener una comprensión intuitiva del orden en que ocurren los eventos cuando dos (o más) hilos trabajan en el mismo valor. El lenguaje, el compilador, el sistema operativo, el procesador ... TODO puede desempeñar un papel y decidir modificar el orden de las operaciones en cuanto a velocidad, practicidad o cualquier otra razón.
La forma adecuada para este tipo de cosas es utilizar herramientas de intercambio de Python ( locks y amigos), o mejor, comunicar datos en lugar de compartirlos, por ejemplo, de esta manera:
from threading import Thread
from Queue import Queue
import time
def thread1(threadname, q):
#read variable "a" modify by thread 2
while True:
a = q.get()
if a is None: return # Poison pill
print a
def thread2(threadname, q):
a = 0
for _ in xrange(10):
a += 1
q.put(a)
time.sleep(1)
q.put(None) # Poison pill
queue = Queue()
thread1 = Thread( target=thread1, args=("Thread-1", queue) )
thread2 = Thread( target=thread2, args=("Thread-2", queue) )
thread1.start()
thread2.start()
thread1.join()
thread2.join()
Solo necesita declarar a
como global en thread2
, de modo que no esté modificando un a
que sea local para esa función.
def thread2(threadname):
global a
while True:
a += 1
time.sleep(1)
En thread1
, no necesita hacer nada especial, siempre y cuando no intente modificar el valor de a
(que crearía una variable local que sombrea la global, use global a
si es necesario)>
def thread1(threadname):
#global a # Optional if you treat a as read-only
while a < 10:
print a