zoukankan      html  css  js  c++  java
  • python网络编程--线程递归锁RLock

    一:死锁

      所谓死锁:是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程成为死锁进程。多个lock会造成死锁

    二:递归锁和线程锁差异

      在threading模块中,定义两种类型的琐:threading.Lock和threading.RLock

      这两种琐的主要区别是:RLock允许在同一线程中被多次acquire。

      而Lock却不允许这种情况。注意:如果使用RLock,那么acquire和release必须成对出现,即调用了n次acquire,

      必须调用n次的release才能真正释放所占用的琐。它们之间有一点细微的区别,通过比较下面两段代码来说明:

      递归锁与普通的互斥锁最大的不同就是,一个锁的对象内部,维护了一个计数器,这个计数器的初始值是0,

      当一个线程acquire一次这个锁时,内部计数器+1,但是,这把锁的计数器一旦大于0,其他的线程是无法拿到这把锁的,只有当前线程可以拿。

      (当前线程acquire一次,计数器+1,release一次计数器-1,所以,当前的线程想要彻底释放掉递归锁,acquire多少次,就要release多少次!!!)

    import threading  
    lock = threading.Lock() #Lock对象  
    lock.acquire()  
    lock.acquire()  #产生了死琐。  
    lock.release()  
    
    lock.release()  
    
     
    
    import threading  
    rLock = threading.RLock()  #RLock对象  
    rLock.acquire()  
    rLock.acquire() #在同一线程内,程序不会堵塞。  
    rLock.release()  
    rLock.release()  

    三:递归锁使用例子

    import threading,time
    
     
    
    def run1():
    
        print("grab the first part data")
    
        lock.acquire()
    
        global num
    
        num +=1
    
        lock.release()
    
        return num
    
    def run2():
    
        print("grab the second part data")
    
        lock.acquire()
    
        global  num2
    
        num2+=1
    
        lock.release()
    
        return num2
    
    def run3():
    
        lock.acquire()
    
        res = run1()
    
        print('--------between run1 and run2-----')
    
        res2 = run2()
    
        lock.release()
    
        print(res,res2)
    
     
    
     
    
    if __name__ == '__main__':
    
     
    
        num,num2 = 0,0
    
        lock = threading.RLock()
    
        for i in range(10):
    
            t = threading.Thread(target=run3)
    
            t.start()
    
     
    
    while threading.active_count() != 1:
    
        print(threading.active_count())
    
    else:
    
        print('----all threads done---')
    
        print(num,num2)

     四:总结

      

      如果同一个线程需要多次去访问同一个共享资源,这个时候,就可以使用递归锁(RLock)

      递归锁的内部,维护了一个Lock对象和一个counter计数变量,counter记录了acquire的次数,从而使得资源可以被多次require。

      直到一个线程所有的acquire都被release,其他的线程才能获得资源。

      所以说RLock可以完全代替Lock,能用递归锁尽量用递归锁!

  • 相关阅读:
    Java线程池,你了解多少?
    Git-常用命令
    CentOS6.6 编译Redis报错:"Newer version of jemalloc required"
    IDEA 常用快捷键
    Java并发编程(4)--生产者与消费者模式介绍
    CSS样式----浮动(图文详解)
    实现键盘记录的e.Whick和keyCode,兼容FireFox和IE
    如何用Fireworks制作经典的扫光字GIF动画
    asp.net中label控件设置字体大小
    [HttpException (0x80004005): 应用程序已预编译,因此不允许使用目录“/App_Code/”。]
  • 原文地址:https://www.cnblogs.com/lixiang1013/p/7064937.html
Copyright © 2011-2022 走看看