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

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

     
  • 相关阅读:
    大叔手记(9):小心使用IHttpHandler下的IsReusable属性
    探讨神奇的需求变更:程序员遭遇车祸成植物人,需求变更将其唤醒
    大型JavaScript应用程序架构模式
    HTML5学习笔记简明版(9):变化的元素和属性
    大叔手记(6):巧用ASP.net MVC3里的HandleErrorAttribute
    大叔手记(7):构建自己的JavaScript模板小引擎
    HTML5学习笔记简明版(10):废弃的元素和属性
    RX/TX/GND是什么
    光影中的十大非常学校
    把音量键改成back键。
  • 原文地址:https://www.cnblogs.com/miaorn/p/11728174.html
Copyright © 2011-2022 走看看