简体   繁体   中英

Python: sharing a list between threads

I'm trying to understand the nuances of how threads interact the variable space they share when running in the same process. The following code shows two functions, prod and consum, that are spun off in different threads. The two functions are given the same list and lock argument: they use da_list to share data and they use the lockguy to synchronize/thread-safe the sharing.

My main question is: when I run this code, it prints out (1, 0, 0, 0, 0 ...) instead of the (1,2,3,4,5,6 ...) I'm expecting. When I remove the l =[0] line in the consum function, I get the expected behavior. Why does the l = [0] screw it up? When consum finishes, da_list should be [0]. A subsequent call of prod should reset da_list to [da_int]. Thanks for the help.

import threading
import time

    def prod(l,lock):
        da_int = 0
        while True:
            with lock:
                time.sleep(0.1)
                da_int += 1
                l[0] = da_int

    def consum(l,lock):

        data = ''

        while True:
            with lock:
                time.sleep(0.1)
                print(l[0])
                l = [0]

    def main():

        da_list = [0]
        lockguy = threading.Lock()


        thread1 = threading.Thread(target = prod, args=(da_list,lockguy))
        thread2 = threading.Thread(target = consum, args=(da_list,lockguy))
        thread1.daemon = True
        thread2.daemon = True
        thread1.start()
        thread2.start()

        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            pass
        finally:
            print('done')




    if __name__ == '__main__':
        main()
l = [0]

You seem to be confused about how assignment works in Python. You seem to think that the above line modifies the object to which l was previously bound. It does not.

The above line creates a new list and binds the local name l to it. Whatever object l may have been bound to previously is no longer related to the name l . Any subsequent use of l in this scope will refer to this newly created list.

Consider this single-threaded code:

a = b = [1]  # a and b are both bound to the same list
print a,b    # [1] [1]
b[0] = 2     # modifies the object to which a and b are bound
print a,b    # [2] [2]
b = [0]      # now b is bound to a new list
print a,b    # [2] [0]

Notice how b[0] = 2 and b = [0] differ. In the first one, the object to which b is bound is modified. In the second, b is bound to a whole new object.

Similarly, l = [0] in your code binds l to a new object and you have lost and cannot regain any reference you had to the original object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM