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原理代码解析

  

 

posted on 2018-09-11 15:23  PiuPiudada  阅读(145)  评论(0编辑  收藏  举报