Глобальная переменная Python с потоком
Как мне поделиться глобальной переменной с потоком?
Пример кода My Python:
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()
Я не знаю, как получить два потока для обмена одной переменной.
Ответы
Ответ 1
Вам просто нужно объявить a
как глобальное значение в thread2
, так что вы не изменяете a
, который является локальным для этой функции.
def thread2(threadname):
global a
while True:
a += 1
time.sleep(1)
В thread1
вам не нужно делать ничего особенного, если вы не пытаетесь изменить значение a
(что создало бы локальную переменную, которая затеняет глобальную, используйте global a
если вам нужно) >
def thread1(threadname):
#global a # Optional if you treat a as read-only
while a < 10:
print a
Ответ 2
В функции:
a += 1
будет интерпретироваться компилятором как assign to a => Create local variable a
, который не является тем, что вы хотите. Вероятно, он с ошибкой a not initialized
завершится ошибкой, так как (локальный) a действительно не был инициализирован:
>>> 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
Вы можете получить то, что хотите, с (очень нахмурившись и по уважительным причинам) ключевое слово global
, например:
>>> def f():
... global a
... a += 1
...
>>> a
1
>>> f()
>>> a
2
В целом, однако, вам следует избегать использования глобальных переменных, которые чрезвычайно быстро выходят из-под контроля. И это особенно актуально для многопоточных программ, где у вас нет механизма синхронизации для thread1
, чтобы знать, когда был изменен a
. Короче: нити сложны, и вы не можете ожидать интуитивного понимания порядка, в котором происходят события, когда два (или более) потока работают с одним и тем же значением. Язык, компилятор, ОС, процессор... могут ВСЕ играть роль и решают изменить порядок операций для скорости, практичности или любой другой причины.
Правильный способ такого использования - использовать инструменты обмена Python (locks
и друзей), или лучше, передавать данные, а не делиться ими, например. например:
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()