1、GIL
2、死锁现象
线程1中:锁A的释放条件是拿到锁B并释放锁B
线程2中:锁B的释放条件是拿到锁A并释放锁A
当线程1拿到了锁A,而进程2拿到了锁B,两个进程的解锁条件都不能满足,即陷入死锁
from threading import Lock, Thread, current_thread
import time
mutex_a = Lock()
mutex_b = Lock()
#
# print(id(mutex_a))
# print(id(mutex_b))
class MyThread(Thread):
# 线程执行任务
def run(self):
self.func1()
self.func2()
def func1(self):
mutex_a.acquire()
# print(f'用户{current_thread().name}抢到锁a')
print(f'用户{self.name}抢到锁a')
mutex_b.acquire()
print(f'用户{self.name}抢到锁b')
mutex_b.release()
print(f'用户{self.name}释放锁b')
mutex_a.release()
print(f'用户{self.name}释放锁a')
def func2(self):
mutex_b.acquire()
print(f'用户{self.name}抢到锁b')
# IO操作
time.sleep(1)
mutex_a.acquire()
print(f'用户{self.name}抢到锁a')
mutex_a.release()
print(f'用户{self.name}释放锁a')
mutex_b.release()
print(f'用户{self.name}释放锁b')
for line in range(10):
t = MyThread()
t.start()
3、递归锁
用于解决死锁问题
模块from threading import RLock
使用:用RLock()
实例化锁对象,如:mutex_a = mutex_b = RLock()
4、信号量
也是一种锁,不过可以设置访问被锁对象的进程数量
模块:from threading import Semaphore
使用:与Lock
对象相同
from threading import Semaphore
from threading import current_thread
from threading import Thread
import time
sm = Semaphore(5) # 加载了sm的对象可以被5个线程同时访问
def task():
sm.acquire()
print(f'{current_thread().name}执行任务')
time.sleep(1)
sm.release()
for line in range(20):
t = Thread(target=task)
t.start()
5、线程队列
FIFO队列:先进先出
LIFO队列:后进先出
优先级队列:根据参数的编码“大小”排序,从左至右逐个比较字符
模块:import queue
使用:
普通的线程队列:先进先出,q = queue.Queue()
LIFO队列:后进先出,q = queue.LifoQueue()
优先级队列:q = queue.PriorityQueue()
优先级队列实例:
参数为多个时候,以元组形式传入
q = queue.PriorityQueue()
q.put(('a优', '先', '娃娃头', 4))
q.put(('a先', '优', '娃娃头', 3))
q.put(('a级', '级', '娃娃头', 2))
print(q.get())
'''
('a优', '先', '娃娃头', 4)'''