Using a global variable with a thread

前端 未结 5 1547
旧时难觅i
旧时难觅i 2020-11-27 15:07

How do I share a global variable with thread?

My Python code example is:

from threading import Thread
import time
a = 0  #global variable

def thread         


        
5条回答
  •  臣服心动
    2020-11-27 15:34

    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 "", line 1, in 
      File "", line 2, in f
    UnboundLocalError: 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
    ... 
    >>> a
    1
    >>> f()
    >>> a
    2
    

    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 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()
    

提交回复
热议问题