zoukankan      html  css  js  c++  java
  • python GIL锁

    Python的GIL锁

      python的GIL锁是什么?

        python内置的一个全局解释器锁,锁的作用就是保证同一时刻一个进程中只有一个县城可以被cpu调度.

      为什么有着吧GIL锁?

        python语言的创始人在开发这门语言时,目的是快速把语言开发出来,如果加上GIL锁(C语言加锁),切换时按照100条字符串指令来进行线程间的切换.

    GIL锁有几种:

      1,Lock(一次放一个)

        线程安全,多线程操作时,内部会让所有线程排队处理.

        如: list/dict/Queue

        非线程安全 + 人 =>排队处理

        

        需求:

          a,创建100个线程,在列表中追加8

          b,创建100个线程

            v=[]

            锁

            - 把自己添加到列表中.

            - 在读取列表的最后一个.

            解锁

         所以锁一个代码块推荐使用以下代码:

      

    import threading
    import time
    
    v = []
    lock = threading.Lock()
    
    def func(arg):
        lock.acquire()
        v.append(arg)
        time.sleep(0.01)
        m = v[-1]
        print(arg,m)
        lock.release()
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    Lock

      2,RLock(一次放一个)

    import threading
    import time
    
    v = []
    lock = threading.RLock()
    def func(arg):
        lock.acquire()
        lock.acquire()
    
        v.append(arg)
        time.sleep(0.01)
        m = v[-1]
        print(arg,m)
    
        lock.release()
        lock.release()
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    RLock

      3,BoundedSemaphore(一次放N个) 又称信号量

    import time
    import threading
    
    lock = threading.BoundedSemaphore(3)
    def func(arg):
        lock.acquire()
        print(arg)
        time.sleep(1)
        lock.release()
    
    
    for i in range(20):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    BoundedSemaphore

      4,Condition(一次放x个)

     有两种方式:

    方式,一

    import time
    import threading
    
    lock = threading.Condition()
    
    
    def func(arg):
        print('线程进来了')
        lock.acquire()
        lock.wait() # 加锁
    
        print(arg)
        time.sleep(1)
    
        lock.release()
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    
    while True:
        inp = int(input('>>>'))
    
        lock.acquire()
        lock.notify(inp)
        lock.release()
    View Code

    方式,二

    def xxxx():
    print('来执行函数了')
    input(">>>")
    # ct = threading.current_thread() # 获取当前线程
    # ct.getName()
    return True
    
    def func(arg):
    print('线程进来了')
    lock.wait_for(xxxx)
    print(arg)
    time.sleep(1)
    
    for i in range(10):
    t =threading.Thread(target=func,args=(i,))
    t.start()
    View Code

      5,Event(一次放所有)

    import time
    import threading
    
    lock = threading.Event()
    
    
    def func(arg):
        print('线程来了')
        lock.wait() # 加锁:红灯
        print(arg)
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    
    input(">>>>")
    lock.set() # 绿灯
    
    
    lock.clear() # 再次变红灯
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    
    input(">>>>")
    lock.set()
    Event

     下面简单介绍一下:

    threading.local

      作用:

        内部自动为每个线程维护一个空间(字典),用于当前存取属于自己的值.保证线程之间的数据隔离.

        {

        线程ID: {...}

        线程ID: {...}

        线程ID: {...}

        }

      示例:

    import time
    import threading
    
    v = threading.local()
    
    def func(arg):
        # 内部会为当前线程创建一个空间用于存储:phone=自己的值
        v.phone = arg
        time.sleep(2)
        print(v.phone,arg) # 去当前线程自己空间取值
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    threading.local

    那么原理是怎么回事呢?

      还是上代码:

    import time
    import threading
    INFO = {}
    class Local(object):
    
        def __getattr__(self, item):
            ident = threading.get_ident()
            return INFO[ident][item]
    
        def __setattr__(self, key, value):
            ident = threading.get_ident()
            if ident in INFO:
                INFO[ident][key] = value
            else:
                INFO[ident] = {key:value}
    
    obj = Local()
    
    def func(arg):
        obj.phone = arg # 调用对象的 __setattr__方法(“phone”,1)
        time.sleep(2)
        print(obj.phone,arg)
    
    
    for i in range(10):
        t =threading.Thread(target=func,args=(i,))
        t.start()
    threading.local原理代码解析

      

  • 相关阅读:
    JavaScript进阶系列06,事件委托
    JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数
    JavaScript进阶系列04,函数参数个数不确定情况下的解决方案
    JavaScript进阶系列03,通过硬编码、工厂模式、构造函数创建JavaScript对象
    JavaScript进阶系列02,函数作为参数以及在数组中的应用
    JavaScript进阶系列01,函数的声明,函数参数,函数闭包
    委托、Lambda表达式、事件系列07,使用EventHandler委托
    委托、Lambda表达式、事件系列06,使用Action实现观察者模式,体验委托和事件的区别
    委托、Lambda表达式、事件系列05,Action委托与闭包
    委托、Lambda表达式、事件系列04,委托链是怎样形成的, 多播委托, 调用委托链方法,委托链异常处理
  • 原文地址:https://www.cnblogs.com/while-number/p/9627788.html
Copyright © 2011-2022 走看看