python的GIL锁:

  是python内置的一个全局解释器锁,锁的作用就是保证同一时刻只有一个线程被CPU调度

为什么有这把锁:

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

设置锁:

  1,Lock(一次放行一个)

import threading
import time

v = []
lock = threading.Lock()

def func(arg):
    lock.acquire()  #设置锁
    v.append(arg)
    time.sleep(0.1)
    m = v[-1]
    print(arg,m)
    lock.release()  #解锁

for i in range(10):
    t = threading.Thread(target=func,args=(i,))
    t.start()
View Code

  2,RLock  递归锁(一次放行一个)  最常用

  跟Lock的用法一样,但是支持锁多次,解多次

import time
import threading

v = []
lock = threading.RLock()
def func(arg):
    lock.acquire()  #设置锁
    lock.acquire()  #设置锁

    v.append(arg)
    time.sleep(0.1)
    m = v[-1]
    print(arg,m)

    lock.release()  #解锁
    lock.release()  #解锁

for i in range(10):
    t = threading.Thread(target=func,args=(i,))
    t.start()
View Code

  3,threading.BoundedSemaphore()   信号量    一次放行固定个数,括号里面有参数,表示一次最多锁几个

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()
View Code

  4,Condition  (一次放任意个)  

方式一:

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

方式二:

import time
import threading

lock = threading.Condition()

def func1():
    print('来执行函数了')
    input('>>>')
    return True

def func2(arg):
    print('线程进来了')
    lock.wait_for(func1) #使用wait_for 传入要执行的函数名
    print(arg)
    time.sleep(1)

for i in range(10):
    t = threading.Thread(target=func2,args=(i,))
    t.start()
View Code

  5,Event  事件   (一次放所有)

    .wait()  加锁

    .set( ) 开锁

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()
View Code

 

总结:

  1,线程安全:多线程操作时,内部会让所有线程排队处理,  list,dict,Queue

  2,线程不安全 + 锁   --->     排队处理

  为什么要加锁:

    非线程安全

    控制一段代码