信号量
为了避免业务开启过多的线程时。我们就可以通过信号量,(Semaphore)来设置指定个数的线程
semapshore.acquire():获取锁
semapshore.release():释放锁
一个例子:过安检
import threading
import os, time
# 一次只允许3个人同时过安检
semapshore = threading.BoundedSemaphore(3)
def run(num):
semapshore.acquire() # 获得信号量的锁
print(f'第{num}个人正在过安检')
time.sleep(2)
semapshore.release() # 释放这把锁
if __name__ == '__main__':
# 创建子线程
thread = []
for i in range(100):
t = threading.Thread(target=run, args=(i,))
t.start()
thread.append(t)
for t in thread:
t.join()
print('主线程执行完毕')
条件变量:
为什么要用condition:
当线程在系统中运行时,线程的调度具有一定的透明性,通常程序无法准确控制线程的轮换执行,如果有需要,Python 可通过线程通信来保证线程协调运行。
如何起作用:
假设系统中有两个线程,这两个线程分别代表存款者和取钱者,现在假设系统有一种特殊的要求,即要求存款者和取钱者不断地重复存款、取钱的动作,而且要求每当存款者将钱存入指定账户后,取钱者就立即取出该笔钱。不允许存款者连续两次存钱,也不允许取钱者连续两次取钱。
为了实现这种功能,可以借助于 Condition 对象来保持协调。使用 Condition 可以让那些己经得到 Lock 对象却无法继续执行的线程释放 Lock 对象,Condition 对象也可以唤醒其他处于等待状态的线程。
事件:
event.isSet():返回event的状态值;
event.wait():如果 event.isSet()==False将阻塞线程;
event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;
event.clear():恢复event的状态值为False
一个例子:上课
from threading import Thread, Event
import time
# 作用 一个线程通知另外一个线程可以执行后面代码了
event = Event()
def student(name):
print('学生%s 正在听课' % name)
event.wait() # 可以带参数 单位:秒 可以等到时间直接运行
print('学生%s 课间活动' % name)
def teacher(name):
print('老师 %s 正在上课' % name)
time.sleep(7)
event.set()
if __name__ == '__main__':
s1 = Thread(target=student, args=('学生1',))
s2 = Thread(target=student, args=('学 生2',))
t1 = Thread(target=teacher, args=('老师1',))
t2 = Thread(target=teacher, args=('老师2',))
s1.start()
s2.start()
t1.start()
t2.start()