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()
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()
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()
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() #解锁
方式二:

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()
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()
总结:
1,线程安全:多线程操作时,内部会让所有线程排队处理, list,dict,Queue
2,线程不安全 + 锁 ---> 排队处理
为什么要加锁:
非线程安全
控制一段代码