zoukankan      html  css  js  c++  java
  • python之多线程变量共享

    因为多线程的时候,线程之间的数据共享,最大的危险是都可以来修改变量例如

    import time ,threading 
    
    balance = 0 
    
    def change_it(n):
        global balance
        balance = balance +n
        balance = balance - n 
    
    def run_thread(n):
        for i in range(1000000):
            change_it(n)
    
    
    
    
    t1 = threading.Thread(target = run_thread , args = (5,))
    t2 = threading.Thread(target = run_thread ,args = (8,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print(balance)

    共享变量balance初始化为0 ,先加后减理论上最后的数值应该是0 ,但是经过t1,t2多次运行后balance的结果就不一定是0

    代码正常运行就像下边:

    t1: x1 = balance + 5 # x1 = 0 + 5 = 5
    t1: balance = x1     # balance = 5
    t1: x1 = balance - 5 # x1 = 5 - 5 = 0
    t1: balance = x1     # balance = 0
    
    t2: x2 = balance + 8 # x2 = 0 + 8 = 8
    t2: balance = x2     # balance = 8
    t2: x2 = balance - 8 # x2 = 8 - 8 = 0
    t2: balance = x2     # balance = 0
        
    结果 balance = 0

    那是因为 balance = balance + n 是先将balance +n的值存进临时变量,然后在将临时变量存入balance

    类似于  

    x = balance + n 

    balance = x

    所以在多次加减赋值之后因为多线程的变量共享导致变量的数据改变

    例如:

    t1: x1 = balance + 5  # x1 = 0 + 5 = 5
    
    t2: x2 = balance + 8  # x2 = 0 + 8 = 8
    t2: balance = x2      # balance = 8
    
    t1: balance = x1      # balance = 5
    t1: x1 = balance - 5  # x1 = 5 - 5 = 0
    t1: balance = x1      # balance = 0
    
    t2: x2 = balance - 8  # x2 = 0 - 8 = -8
    t2: balance = x2   # balance = -8
    
    结果 balance = -8

    所以要保证数据的正确要加锁,保证在一个线程运算时,只能由一个线程去读写。

    修改如下:
    import time, threading
    lock = threading.Lock()
    balance = 0 
    
    def change_it(n):
        global balance
        balance = balance + n 
        balance = balance - n 
    
    def run_thread(n):
        for i in range(100000):
            lock.acquire()
            try:
                    change_it(n)
            finally:
                    lock.release()
    
    t1 = threading.Thread(target=run_thread, args=(5,))
    t2 = threading.Thread(target=run_thread, args=(8,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print(balance)

    结果一直保持0

    这样保证变量在调用时不会被其他的线程读写

     
  • 相关阅读:
    洛谷 P2969 [USACO09DEC]音符Music Notes
    洛谷 P2646 数数zzy
    洛谷 P1605 迷宫
    洛谷 P1157 组合的输出
    洛谷 P1449 后缀表达式
    洛谷 P1205 [USACO1.2]方块转换 Transformations
    洛谷 P1599 结算日
    洛谷 P2909 [USACO08OPEN]牛的车Cow Cars
    洛谷 P2118 比例简化
    3.2、spark集群运行应用之第三方jar的处理方式
  • 原文地址:https://www.cnblogs.com/miaorn/p/11728174.html
Copyright © 2011-2022 走看看