• python 线程锁


     在多线程中,同一个变量能被所有线程共享,这个变量能被任何一个线程修改。

    看一个实验。

    启动5个线程,每个线程把全局变量加1

    import threading
    import time
    
    t_objs = []
    def run(n):
        global num
        num+=1
    num = 0
    
    for i in range(5):
        t = threading.Thread(target=run,args=("t-%s" %i,))
        t.start()
        t_objs.append(t)
    
    for t in t_objs:
        t.join()
    print('num:',num) #num: 5
    

     启动了5个线程,每个线程加1,一共是5个,所以结果是5没有问题。

    python2.7下执行:

    50个线程,num相加50次,也没有问题。1000个线程相加也是没有问题的。

    尝试相减,启动1000个线程,每个线程减1。

    子线程不等待,主线程等待3s。

    根据GIL同一时间只有一个线程在执行,但是并不能保证数据是正确的。这个现象在其它系统中会出现。

     

    线程1拿到的count = 0; 但是线程1没有执行完就被挂起了。紧接着执行线程2,线程2执行完成,并且把count=1赋值给count。这个时候线程1又继续执行,但是之前的线程因为被挂起,所以数据保存在了寄存器里面,并没有在次取数据,这个时候count还是0。那么线程1执行完count++之后count=1,又赋值给了count。最后count的数值还是1,这个计算并不准确。

    这个怎么保证数据的准确性呢?

    理想的状态下,我们希望启动线程时并行,计算数值时串行。

    这个时候需要用户自己加一个锁,这个锁和GIL无关。这个锁是保证同一时间只有一个线程在修改数据。

    import threading
    import time
    
    t_objs = []
    def run(n):
        lock.acquire() #添加锁
        global num
        num+=1
        lock.release()#释放锁
    num = 0
    lock = threading.Lock() #锁的实例
    for i in range(500):
        t = threading.Thread(target=run,args=("t-%s" %i,))
        t.start()
        t_objs.append(t)
    
    for t in t_objs:
        t.join()
    print('num:',num) #num: 500
    

    可以 验证计算是否是串行,在计算的时候sleep.

    import threading
    import time
    
    t_objs = []
    def run(n):
        lock.acquire() #添加锁
        global num
        num+=1
        time.sleep(1)
        lock.release()#释放锁
    num = 0
    lock = threading.Lock() #锁的实例
    for i in range(5):
        t = threading.Thread(target=run,args=("t-%s" %i,))
        t.start()
        t_objs.append(t)
    
    for t in t_objs:
        t.join()
    print('num:',num) #等待5s num: 5
    

     以上现象在2.X会出现。

  • 相关阅读:
    C#中ConnectionStrings和AppSettings的区别
    VS2010 生成的程序在其他电脑上不运行的问题
    装修经验
    在Linux下安装rar for linux
    判断二叉搜索树的后序遍历序列
    二维数组中的查找某个数
    Spring MVC执行原理
    将二叉搜索树转换成一个排序的双向链表
    打印二叉树中所有分支之和等于某个数
    ObjectiveC中public、protected、private的使用[转]
  • 原文地址:https://www.cnblogs.com/qing-chen/p/7679887.html
Copyright © 2020-2023  润新知