事件Event:
同进程的一样,线程的一个关键特性是每个线程都是独立运行且状态不可预测。如果程序中的其他线程需要通过判断某个线程的状态来确定自己下一步的操作,这时线程同步问题就会变得非常棘手。为了解决这些问题,我们需要使用threading库中的Event对象。 对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生。
在初始情况下,Event对象中的信号标志被设置为false。如果有线程等待一个Event对象, 而这个Event对象的标志为false,那么这个线程将会被一直阻塞直至该标志为真。一个线程如果将一个Event对象的信号标志设置为真,它将唤醒所有等待这个Event对象的线程。如果一个线程等待一个已经被设置为真的Event对象,那么它将忽略这个事件,继续执行。
Event方法:
1、event.isSet():当且仅当内部标志为True
时返回True
。
2、event.set():将内部标志设置为True
。所有等待它成为True
的线程都被唤醒。当标志保持在True
的状态时,线程调用wait()
是不会阻塞的。
3、event.clear():将内部标志重置为False
。随后,调用wait()
的线程将阻塞,直到另一个线程调用set()
将内部标志重新设置为True
。
4、event.wait():阻塞直到内部标志为真。如果内部标志在wait()
方法调用时为True
,则立即返回。否则,则阻塞,直到另一个线程调用set()
将标志设置为True
,或发生超时。
红绿灯示例:
1 import threading 2 import time 3 4 event = threading.Event() # 实例化event 5 6 def Light(): 7 count = 0 8 while True: 9 if count > 5 and count < 10: 10 event.set() 11 # print("红灯ing...") 12 time.sleep(1) 13 elif count > 10: 14 event.clear() 15 count = 0 16 else: 17 # print("绿灯ing...") 18 time.sleep(1) 19 count += 1 20 21 light = threading.Thread(target=Light) 22 light.start() 23 24 def Car(name): 25 while True: 26 if event.is_set(): 27 print("[%s] going...." % name) 28 time.sleep(1) 29 else: 30 print("[%s] 等待绿灯。。。" % name) 31 event.wait() 32 33 car1 = threading.Thread(target=Car,args=("car1",)) 34 car1.start()
执行结果:
1 [car1] 等待绿灯。。。 2 [car1] going.... 3 [car1] going.... 4 [car1] going.... 5 [car1] going.... 6 [car1] going.... 7 [car1] going.... 8 [car1] 等待绿灯。。。 9 [car1] going.... 10 [car1] going.... 11 [car1] going.... 12 [car1] going.... 13 [car1] going.... 14 [car1] going.... 15 [car1] 等待绿灯。。。 16 [car1] going.... 17 [car1] going.... 18 19 Process finished with exit code -1