zoukankan      html  css  js  c++  java
  • 学习日记0907 GIL全局解释器锁 死锁与递归锁 信号量 Event事件 线程的queue

    GIL全局解释器锁(*****)

      为什么会出现GIL全局解释器锁

        因为Cpython解释器的垃圾回收机制不是线性安全的

        通俗来讲就是同一个进程中垃圾回收线程和一些要运行的线程的并发的,如果没有GIL全局解释器锁,线程运行过程中产生的数据,会因为并发的问题而被垃圾回收机制回收,

        这里要提一点为什么垃圾回收机制会回收有用的数据(前提没有GIL解释器锁,垃圾回收线程和普通线程并发),因为线程运行过程中产生了数据但是还没来得急赋变量名,或者说引用计数还没来得急改,就被垃         圾回收线程发现并且回收,这时就会产生冲突,这时我们就需要应用GIL全局解释器锁

      什么是GIL全局解释器锁

        全局解释器锁GIL本质就是一种互斥锁,每个进程都会有一个GIL,进程中的线程需要抢到GIL才能拿到cpython解释器的执行权限,才可以执行代码

        GIL全局解释器使得在cpython中同一个进程的线程无法完成并行,只能并发. 但是不同的进程可以实现并行

    自义定互斥锁和GIL全局解释器锁

      那么在cpython中一个进程中即含有自义定互斥锁又有GIL全局解释器锁,它们是怎么运行的呢

        前提:多线程执行同一代码

        同一进程中多个线程需要先抢到GIL全局解释器锁才能运行代码,再抢到GIL之后会得到自义定锁,若在得到自义定锁之后遇到了oi操作,此时会释放GIL锁,但是不会释放自义定互斥锁,其它的线程及时得到了GIL锁也不能执行自义定互斥锁中的代码,因为没有得到自义定互斥锁,这时GIL锁还是会回到有自定锁的线程手中,只有在有自定义互斥锁的线程执行完代码释放自定义互斥锁,并且释放了GIL锁之后其它的线程才能继续运行

    死锁与递归锁现象

      

    from threading import Thread,Lock,RLock
    import time
    
    # mutexA=Lock()
    # mutexB=Lock()
    mutexB=mutexA=RLock()
    
    
    class Mythead(Thread):
        def run(self):
            self.f1()
            self.f2()
    
        def f1(self):
            mutexA.acquire()
            print('%s 抢到A锁' %self.name)
            mutexB.acquire()
            print('%s 抢到B锁' %self.name)
            mutexB.release()
            mutexA.release()
    
        def f2(self):
            mutexB.acquire()
            print('%s 抢到了B锁' %self.name)
            time.sleep(2)
            mutexA.acquire()
            print('%s 抢到了A锁' %self.name)
            mutexA.release()
            mutexB.release()
    
    if __name__ == '__main__':
        for i in range(100):
            t=Mythead()
            t.start()

    信号量(限制一个锁可以给多少个人使用)

    from threading import Thread,Semaphore
    import time,random
    sm=Semaphore(5)
    
    def task(name):
        sm.acquire()
        print('%s 正在上厕所' %name)
        time.sleep(random.randint(1,3))
        sm.release()
    
    if __name__ == '__main__':
        for i in range(20):
            t=Thread(target=task,args=('路人%s' %i,))
            t.start()

    Event事件

      

    from threading import Thread,Event
    import time
    
    event=Event()
    
    def light():
        print('红灯正亮着')
        time.sleep(3)
        event.set() #绿灯亮
    
    def car(name):
        print('车%s正在等绿灯' %name)
        event.wait() #等灯绿
        print('车%s通行' %name)
    
    if __name__ == '__main__':
        # 红绿灯
        t1=Thread(target=light)
        t1.start()
        #
        for i in range(10):
            t=Thread(target=car,args=(i,))
            t.start()

    Queue


      队列型(先进先出)

    queue.Queue() #先进先出
    q=queue.Queue(3)
    q.put(1)
    q.put(2)
    q.put(3)
    print(q.get())
    print(q.get())
    print(q.get())

      堆栈型(先进后出)

    queue.LifoQueue() #后进先出->堆栈
    q=queue.LifoQueue(3)
    q.put(1)
    q.put(2)
    q.put(3)
    print(q.get())
    print(q.get())
    print(q.get())

      优先级型(根据优先级选择)

    q=queue.PriorityQueue(3) #优先级,优先级用数字表示,数字越小优先级越高
    q.put((10,'a'))
    q.put((-1,'b'))
    q.put((100,'c'))
    print(q.get())
    print(q.get())
    print(q.get())
  • 相关阅读:
    Linux外部设备的使用
    Linux硬件信息查询
    Linux中swap分区设置
    状态检测型防火墙
    CentOS更换源,亲测可用
    Linux文件权限序列简述
    Linux终端打印文本色彩
    Linux 系统命令之netstat
    Linux配置DNS服务器
    水题一枚
  • 原文地址:https://www.cnblogs.com/jianhaozhou/p/9605062.html
Copyright © 2011-2022 走看看