zoukankan      html  css  js  c++  java
  • 锁-lock,信号量4

    1. 全局解释器锁,保证同一时间只有一个线程在执行,但是由于它是把数据copy成了两份,所以

    只有全局解释器锁的时候,数据加减照样出错了。

    2.用户态的锁,保证同一时间,只有一个线程在真真正正地修改数据。

    修改数据之前,先加一把锁。修改完了以后,释放锁。修改数据的时候,把程序变成串行的。

    #主线程启动子线程之后,两者是并行的,相互之间是独立的。
    import threading,time
    
    def run(n):
        lock.acquire() #获取一把锁
        global num   #把num声明成全局变量以后,才能够进行修改。
        num+=1
        time.sleep(1)
        lock.release() #释放锁
    
    lock=threading.Lock() #生产一个锁的实例
    num=0 #全局变量
    t_objs=[]
    start_time=time.time()
    
    for i in range(10):
        t=threading.Thread(target=run,args=("t-%s"%i,))
        t.start()
        t_objs.append(t)
    for t in t_objs:
        t.join() #所有线程都执行完毕
    
    print('----All threads has finished',threading.current_thread(),threading.active_count())
    print('num:',num)
    print('Cost time:',time.time()-start_time)
    

     运行结果:发现确实花费了10s多。

    ----All threads has finished <_MainThread(MainThread, started 9908)> 1
    num: 10
    Cost time: 10.003000259399414
    
    Process finished with exit code 0
    

     3. 递归锁(又叫互斥锁),因为有多把锁,找不到出去的锁,会陷入死循环。说白了就是在一个大锁中还要再包含子锁

    locks={
        door1:key1,
        door2:key2,
    }
    

     程序摘抄自老师的博客:

    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)
    

    4.信号量Semaphore

    互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。最多同时有3个在执行,当有1个执行完了的时候,就会又放1个进去。发现程序是5个5个一组进行执行。

    import threading, time
    
    def run(n):
        semaphore.acquire()
        time.sleep(1)
        print("run the thread: %s
    " % n)
        semaphore.release()
    
    if __name__ == '__main__':
    
        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---')
    
  • 相关阅读:
    延迟加载时发生no session错误的解决办法
    零零散散的一些知识点(一)
    零零散散的一些知识点(二)
    自己写的一个日历表
    js复制网址
    load方法在延迟加载时可能出现的错误。
    JSON基本介绍
    JBOSS4.0 JDBC数据源配置大全
    EJB学习笔记一
    Android程序完全退出的方法
  • 原文地址:https://www.cnblogs.com/momo8238/p/7345703.html
Copyright © 2011-2022 走看看