zoukankan      html  css  js  c++  java
  • python递归锁与信号量

    递归锁

    一把大锁在加一把小锁。

    import threading
    import 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.Lock()
        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)
    

     过程分享:
    1、启动10个线程,每个线程都执行run3。

    2、run3中先加了一个锁,然后执行run1。

    3、run1中也加了一个锁,计算完成后解锁返回数据。执行run2。

    4、run2中同样加了一个锁,计算完成后解锁打印run1,run2返回值。

    5、最后打印num1、num2。

    需要注意的是在执行过程中是有两把锁的,一个run3,一个run1或者run2。

    运行结果:

    11
    11
    11
    11
    11
    11
    11
    11
    # 程序进入死循环
    

     死循环的原因是解锁的时候 钥匙拿错了导致进程退不出来,解决死锁就是要使用递归锁。

    threading.Lock() 改为 threading.RLock()

    import threading
    import 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(1):
            t = threading.Thread(target=run3)
            t.start()
    
    while threading.active_count() != 1:
        print(threading.active_count())
    else:
        print('----all threads done---')
        print(num, num2)
    

    运行结果

    grab the first part data
    --------between run1 and run2-----
    grab the second part data
    1 1
    ----all threads done---
    1 1
    

     实现原理:

    解锁的时候找对应的钥匙。

     信号量

    互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。简单的说就是互斥锁同一时间只能要一个线程修改数据,信号量同一时间可以让多个线程修改数据。信号量可以挂多吧锁。

    import threading,time
     
    def run(n):
        semaphore.acquire()
        time.sleep(1)
        print("run the thread: %s
    " %n)
        semaphore.release()
     
    if __name__ == '__main__':
     
        num= 0
        semaphore  = threading.BoundedSemaphore(5) #最多允许5个线程同时运行
        for i in range(20):
            t = threading.Thread(target=run,args=(i,))
            t.start()
     
    while threading.active_count() != 1:
        pass #print threading.active_count()
    else:
        print('----all threads done---')
        print(num)
    

     每一个进程结束了就重新添加一个新的进去。

  • 相关阅读:
    linux oracle命令行窗口命令上下翻阅
    oracle 转移表空间
    perl字符集处理
    Perl解析JSON数据精解
    处理外壳PROC
    FileIsExe
    写壳前的设计
    SEH结构化异常处理03
    SEH结构化异常处理02
    博客首记
  • 原文地址:https://www.cnblogs.com/qing-chen/p/7680101.html
Copyright © 2011-2022 走看看