公众号:pythonislover
今天这篇文章大概介绍下python多线程中的同步条件Event,信号量(Semaphore)和队列(queue),这是我们多线程系列的最后一篇文章,以后将会进入python多进程的系列。
同步条件(Event)
先说说为什么我们需要这个同步条件,我们的python多线程在执行task过程中,是相互竞争的,大家都可以先获取cpu的执行权限,这就是问题所在的地方,每个线程都是独立运行且状态不可预测,但是我们想想如果我们的业务中需要根据情况来决定线程的执行顺序,也就是程序中的其他线程需要通过判断某个线程的状态来确定自己下一步的操作,这时候我们就需要使用threading库中的Event对象。 对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生。
在 初始情况下,Event对象中的信号标志被设置为假,如果有线程等待一个Event对象, ,那么这个线程将会被一直阻塞直至该标志为真。
一个线程如果将一个Event对象的信号标志设置为真,它将唤醒所有等待这个Event对象的线程继续执行。
Event的方法如下:
event.isSet():返回event的状态值
event.wait():如果 event.isSet()==False,将阻塞线程触发event.wait()
event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待执行
event.clear():恢复event的状态值为False
下面段代码例子:
首先我们描述一个场景
1.老师说这堂课我们要做测试卷子,做完才能放学
2.学生叫苦连天,啊啊啊啊啊啊
3.学生做试卷中
4.做完试卷放学回家
import threading
import time
class Teacher(threading.Thread):
def run(self):
print("大家现在要考试")
print(event.isSet())
event.set()
time.sleep(3)
print("考试结束")
print(event.isSet())
event.set()
class Student(threading.Thread):
def run(self):
event.wait()
print("啊啊啊啊啊啊")
time.sleep(1)
event.clear()
event.wait()
print("下课回家")
if __name__=="__main__":
event=threading.Event()
threads=[]
for i in range(10):
threads.append(Student())
threads.append(Teacher())
for t in threads:
t.start()
for t in threads:
t.join()
我们来解释下上面代码的执行流程
1.模拟1个老师和10个学生,进行考试,我们需要的目的是学生线程要等待老师线程说完“大家现在考试”,然后学生线程去考试,之后老师线程说“考试结束”,学生线程放学回家,学生线程的执行与否取决于老师线程,所以这里用的