Python的GIL锁
- Python内置的一个全局解释器锁,锁的作用就是保证同一时刻一个进程中只有一个线程可以被cpu调度。
为什么有这把GIL锁?
答:Python语言的创始人在开发这门语言时,目的快速把语言开发出来,如果加上GIL锁(C语言加锁), 切换时按照100条字节指令来进行线程间的切换。
一、锁: Lock
1、一次放一个
threading.Lock
线程安全,多线程操作时,内部会让所有线程排队处理。如:list/dict/ Queue 线性不安全 + 人 =》 排队处理

import threading
v = []
def func(arg):
v.append(arg) # 线程安全
print(v)
for i in range(10):
t =threading.Thread(target=func,args=(i,))
t.start()

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

import threading
import time
v = []
lock = threading.RLock()
def func(arg):
lock.acquire()
lock.acquire() #RLock可以进行多次加锁
v.append(arg)
time.sleep(0.01)
m = v[-1]
print(arg,m)
lock.release() #RLock多次释放锁
lock.release()
for i in range(10):
t =threading.Thread(target=func,args=(i,))
t.start()
2、一次放指定N个
BoundedSemaphore

import time
import threading
lock = threading.BoundedSemaphore(3) #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()
3、一次释放N 个
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.wait() 就是代表释放几个线程
lock.release()
# ############## 方式二 ##############
def xxxx():
print('来执行函数了')
input(">>>")
# ct = threading.current_thread() # 获取当前线程
# ct.getName()
return True
def func(arg):
print('线程进来了')
lock.wait_for(xxxx) #等待xxxx中的东西执行完成之后,此线程才会接着往下走
print(arg)
time.sleep(1)
for i in range(10):
t =threading.Thread(target=func,args=(i,))
t.start()
4、一次放所有
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()
总结 线程安全,列表和字典线程安全; 为什么要加锁? - 非线程安全 - 控制一段代码
