Event
线程的一个关键特性是每个线程都是独立运行且状态不可预测。如果程序中的其 他线程需要通过判断某个线程的状态来确定自己下一步的操作,这时线程同步问题就会变得非常棘手。为了解决这些问题,我们需要使用threading库中的Event对象。 对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生。在 初始情况下,Event对象中的信号标志被设置为假。如果有线程等待一个Event对象, 而这个Event对象的标志为假,那么这个线程将会被一直阻塞直至该标志为真。一个线程如果将一个Event对象的信号标志设置为真,它将唤醒所有等待这个Event对象的线程。如果一个线程等待一个已经被设置为真的Event对象,那么它将忽略这个事件, 继续执行
from threading import Event 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 on 听课 " % name) event.wait(2) print("学生 %s 课件活动 " % name) def teacher(name): print("老师 %s on 上课" % name) time.sleep(3) event.set() if __name__ == "__main__": stu1 = Thread(target=student,args=("cmz",)) stu2 = Thread(target=student,args=("leco",)) stu3 = Thread(target=student,args=("loocha",)) teacher1 = Thread(target=teacher,args=("caimengzhi",)) stu1.start() stu2.start() stu3.start() teacher1.start()
学生 cmz on 听课
学生 leco on 听课
学生 loocha on 听课
老师 caimengzhi on 上课
学生 cmz 课件活动
学生 loocha 课件活动
学生 leco 课件活动
学生只能等老师结束也及时event.set()才能继续
from threading import Thread,Event,current_thread import time event = Event() def conn(): n = 0 while not event.is_set(): if n == 3: print("%s too many times" % current_thread().getName()) return print("%s try %s" %(current_thread().getName(),n)) event.wait(0.5) n += 1 def check(): print("%s is checking" % current_thread().getName()) time.sleep(5) event.set() if __name__ == "__main__": for i in range(3): t = Thread(target=conn) t.start() t = Thread(target=check) t.start()
Thread-1 try 0 Thread-2 try 0 Thread-3 try 0 Thread-4 is checking Thread-2 try 1 Thread-1 try 1 Thread-3 try 1 Thread-1 try 2 Thread-2 try 2 Thread-3 try 2 Thread-1 too many times Thread-2 too many times Thread-3 too many times