zoukankan      html  css  js  c++  java
  • 多线程——GIL信号量递归锁

    互斥锁

    1、什么是GIL(global interpreter lock)?
    GIL是一个互斥锁:保证数据的安全(牺牲效率来获取数据的安全),阻止同一个进程内的多线=线程同时执行(不能并行但是能实现并发)
    2、为什么会有GIL?
    由于cpython解释器的内存管理不是线程安全的(垃圾回收机制的存在)
    同一进程想的多线程不能实现并行但是可以实现并发,不同进程下可以实现并行

    问题:Python多线程是不是就没有用:

    举个例子:
    四个任务:计算密集任务,每个任务10s
    单核情况下:
    		多线程好点,消耗资源少,速度快
    多核情况下:
    		开四个进程,10s多点
    		开四个线程,40s多点
    
    四个任务:IO密集任务,每个任务10s
    单核情况下:
    		多线程好点
    多核情况下:
    		多线程好点
    
    总结:多线程和多进程都有自己的优点和缺点,根据项目需求合理选择
    对于不同的数据要加不同的锁进行,GIL不能保证数据的安全,他只针对线程。保证同一个进程下的多个线程是安全的
    

    3、死锁和递归锁

    自定义锁(Lock):自定义锁必须一次acquire 必须对应一次release,不能连续需acquire
    递归锁(RLock):可以连续acquire,每acquire一次,计数加1:针对的是第一抢到的人

    from threading import Thread,Lock,RLock
    import time
    
    """
    自定义锁一次acquire必须对应一次release,不能连续acquire
    递归锁可以连续的acquire,每acquire一次计数加一:针对的是第一个抢到我的人
    """
    import random
    #
    # mutexA = Lock()
    # mutexB = Lock()
    mutexA = mutexB = RLock()  # 抢锁之后会有一个计数 抢一次计数加一 针对的是第一个抢到我的人
    
    class MyThead(Thread):
        def run(self):
            self.func1()
            self.func2()
    
        def func1(self):
            mutexA.acquire()
            print('%s 抢到A锁了'%self.name)
            mutexB.acquire()
            print('%s 抢到B锁了' % self.name)
            mutexB.release()
            print('%s 释放了B锁'%self.name)
            mutexA.release()
            print('%s 释放了A锁'%self.name)
    
        def func2(self):
            mutexB.acquire()
            print('%s 抢到了B锁'%self.name)
            time.sleep(1)
            mutexA.acquire()
            print('%s 抢到A锁了' % self.name)
            mutexA.release()
            print('%s 释放了A锁' % self.name)
            mutexB.release()
            print('%s 释放了B锁' % self.name)
    
    
    for i in range(100):
        t = MyThead()
        t.start()
    

    4、信号量

    sm = Semaphore()

    from threading import Thread,Semaphore
    import time
    import random
    sm = Semaphore(5)  # 五个厕所五把锁
    # 跟你普通的互斥锁区别在于,普通的互斥锁是独立卫生间,所有人抢一把锁
    # 信号量 公共卫生间 有多个坑,所有人抢多把锁
    
    
    
    def task(name):
        sm.acquire()
        print('%s正在蹲坑'%name)
        # 模拟蹲坑耗时
        time.sleep(random.randint(1,5))
        sm.release()
    
    
    if __name__ == '__main__':
        for i in range(20):
            t = Thread(target=task,args=('伞兵%s号'%i,))
            t.start()
    

    5、线程queue:

    queue分为三类:
    1.普通q:q=queue.Queue(3)
    2.先进后出:q = queue.LifoQueue(5)
    3.优先级q:q = queue.PriorityQueue()
    #普通q
    # q=queue.Queue(3)
    # q.put(1)
    # q.put(2)
    # q.put(3)
    # print(q.get())
    # print(q.get())
    # print(q.get())
    
    # 先进后出q
    # q = queue.LifoQueue(5)
    # q.put(1)
    # q.put(2)
    # q.put(3)
    # q.put(4)
    # print(q.get())
    
    
    
    # 优先级q
    # q = queue.PriorityQueue()
    # q.put((10,'a'))
    # q.put((-1,'b'))
    # q.put((100,'c'))
    # print(q.get())
    # print(q.get())
    # print(q.get())
    

      


     



  • 相关阅读:
    [HNOI2010]CITY 城市建设

    [HNOI2011]数学作业
    [NOI2012]美食节
    [HEOI2014]大工程
    [HEOI2013]ALO(待更)
    [HEOI2016/TJOI2016]序列
    贪食蛇(未完待续)
    [HEOI2016/TJOI2016]字符串
    bzoj 2437[Noi2011]兔兔与蛋蛋 黑白染色二分图+博弈+匈牙利新姿势
  • 原文地址:https://www.cnblogs.com/king-home/p/10832307.html
Copyright © 2011-2022 走看看