Event
一个线程需要根据另外一个线程的状态来确定自己的下一步操作,需要调用threading库中Event对象;Event包含一个可由线程设置的信号标志,在初始情况下,event对象的标志位为假(false);。如果一个线程等待一个event对象,而这个event对象标志为假,那么这个线程将会被一直阻塞到标志为真(true);。
同理:一个线程如果将一个event对象的信号标志设置为真,它将唤醒所有等待这个event对象的线程。
如果一个线程等待一个已经被设置为真的event对象,那么它将忽略这个事件,继续执行。
#!/usr/bin/env python # encoding: utf-8 """ @author: 侠之大者kamil @file: Event_test.py @time: 2016/3/23 9:42 """ from threading import Thread ,Event import time def countdown(n,started_evt): print('countdown starting',time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())) started_evt.set() while n >0: print("T-time_kamil:",n) n -=1 time.sleep(2) started_evt = Event() print("Launching countdown",time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())) t = Thread(target=countdown,args=(5,started_evt)) t.start() started_evt.wait() print("countdown is running",time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))
结果:
C:Python34python.exe D:/kamil/Documents/py/process/Event_test.py Launching countdown 2016-03-23 16:03:28 countdown starting 2016-03-23 16:03:28 T-time_kamil: 5 countdown is running 2016-03-23 16:03:28 T-time_kamil: 4 T-time_kamil: 3 T-time_kamil: 2 T-time_kamil: 1 Process finished with exit code 0
Condition
如果一个线程需要不停重复的使用event对象,最好使用condition对象实现一个周期定时器,每当定时器超时的时候,其他线程都可以检测到:
#!/usr/bin/env python # encoding: utf-8 """ @author: 侠之大者kamil @file: event_test2.py @time: 2016/3/23 14:45 """ import time,threading class PeriodicTimer: def __init__(self,interval): self._interval = interval self._flag = 0 self._cv = threading.Condition()#使用Condition对象可以在某些事件触发或者达到特定的条件后才处理数据 def start(self): t = threading.Thread(target=self.run) t.daemon = True#Daemon线程表明整个Python主程序只有在Daemon子线程运行时可以退出. t.start() def run(self): while True: time.sleep(self._interval) with self._cv: self._flag ^=1 self._cv.notify_all() def wait_for_tick(self): with self._cv: last_flag = self._flag while last_flag == self._flag: self._cv.wait() ptimer = PeriodicTimer(5) ptimer.start() def countdown(nticks): while nticks > 0 : ptimer.wait_for_tick() print("t_time",nticks) nticks -= 1 def countup(last): n = 0 while n < last: ptimer.wait_for_tick() print("counting",n) n +=1 threading.Thread(target=countdown,args=(6,)).start() threading.Thread(target=countup,args=(3,)).start()
结果:
C:Python34python.exe D:/kamil/Documents/py/process/event_test2.py t_time 6 counting 0 t_time 5 counting 1 t_time 4 counting 2 t_time 3 t_time 2 t_time 1 Process finished with exit code 0
如上文中event在为真后,所有等待的进程都要开始,如果只想唤起一个进程,那可以使用Condition 对象来替代