Подтвердить что ты не робот

Глобальная переменная 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()

Я не знаю, как получить два потока для обмена одной переменной.

4b9b3361

Ответ 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()