Using a global variable with a thread Using a global variable with a thread python python

Using a global variable with a thread


You just need to declare a as a global in thread2, so that you aren't modifying an a that is local to that function.

def thread2(threadname):    global a    while True:        a += 1        time.sleep(1)

In thread1, you don't need to do anything special, as long as you don't try to modify the value of a (which would create a local variable that shadows the global one; use global a if you need to)>

def thread1(threadname):    #global a       # Optional if you treat a as read-only    while a < 10:        print a


In a function:

a += 1

will be interpreted by the compiler as assign to a => Create local variable a, which is not what you want. It will probably fail with a a not initialized error since the (local) a has indeed not been initialized:

>>> a = 1>>> def f():...     a += 1... >>> f()Traceback (most recent call last):  File "<stdin>", line 1, in <module>  File "<stdin>", line 2, in fUnboundLocalError: local variable 'a' referenced before assignment

You might get what you want with the (very frowned upon, and for good reasons) global keyword, like so:

>>> def f():...     global a...     a += 1... >>> a1>>> f()>>> a2

In general however, you should avoid using global variables which become extremely quickly out of hand. And this is especially true for multithreaded programs, where you don't have any synchronization mechanism for your thread1 to know when a has been modified. In short: threads are complicated, and you cannot expect to have an intuitive understanding of the order in which events are happening when two (or more) threads work on the same value. The language, compiler, OS, processor... can ALL play a role, and decide to modify the order of operations for speed, practicality or any other reason.

The proper way for this kind of thing is to use Python sharing tools (locks and friends), or better, communicate data via a Queue instead of sharing it, e.g. like this:

from threading import Threadfrom queue import Queueimport timedef thread1(threadname, q):    #read variable "a" modify by thread 2    while True:        a = q.get()        if a is None: return # Poison pill        print adef thread2(threadname, q):    a = 0    for _ in xrange(10):        a += 1        q.put(a)        time.sleep(1)    q.put(None) # Poison pillqueue = 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()


A lock should be considered to use, such as threading.Lock. See lock-objects for more info.

The accepted answer CAN print 10 by thread1, which is not what you want. You can run the following code to understand the bug more easily.

def thread1(threadname):    while True:      if a % 2 and not a % 2:          print "unreachable."def thread2(threadname):    global a    while True:        a += 1

Using a lock can forbid changing of a while reading more than one time:

def thread1(threadname):    while True:      lock_a.acquire()      if a % 2 and not a % 2:          print "unreachable."      lock_a.release()def thread2(threadname):    global a    while True:        lock_a.acquire()        a += 1        lock_a.release()

If thread using the variable for long time, coping it to a local variable first is a good choice.