import threading import logging import time logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s [%(threadName)s] %(message)s') defworker(event): whilenot event.is_set(): logging.debug('in worker fun, event is set ? {0}'.format(event.is_set())) logging.debug('event is set') defset(event): time.sleep(1) event.set() logging.debug('in set fun, event is set ? {0}'.format(event.is_set())) if __name__ == '__main__': event = threading.Event() w = threading.Thread(target=worker, args=(event,), name="worker") w.start() s = threading.Thread(target=set, args=(event,), name="set") s.start()
在上边的代码中定义了两个函数,并在测试代码上启用两个线程分别调用这两个函数,在调用前要初始化event对象。运行上边的代码会发现一直输出2016-08-14 20:36:49,059 DEBUG [worker] in worker fun, event is set ? False,即是调用worker函数的线程在不断执行,1秒后输出了2016-08-14 20:36:49,063 DEBUG [set] in set fun, event is set ? True,紧跟着输出2016-08-14 20:36:49,063 DEBUG [worker] event is set,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
2016-08-14 20:36:49,061 DEBUG [worker] in worker fun, event is set ? False 2016-08-14 20:36:49,061 DEBUG [worker] in worker fun, event is set ? False 2016-08-14 20:36:49,061 DEBUG [worker] in worker fun, event is set ? False 2016-08-14 20:36:49,061 DEBUG [worker] in worker fun, event is set ? False 2016-08-14 20:36:49,061 DEBUG [worker] in worker fun, event is set ? False 2016-08-14 20:36:49,062 DEBUG [worker] in worker fun, event is set ? False 2016-08-14 20:36:49,062 DEBUG [worker] in worker fun, event is set ? False ....略..... 2016-08-14 20:36:49,062 DEBUG [worker] in worker fun, event is set ? False 2016-08-14 20:36:49,062 DEBUG [worker] in worker fun, event is set ? False 2016-08-14 20:36:49,062 DEBUG [worker] in worker fun, event is set ? False 2016-08-14 20:36:49,062 DEBUG [worker] in worker fun, event is set ? False 2016-08-14 20:36:49,062 DEBUG [worker] in worker fun, event is set ? False 2016-08-14 20:36:49,062 DEBUG [worker] in worker fun, event is set ? False 2016-08-14 20:36:49,062 DEBUG [worker] in worker fun, event is set ? False 2016-08-14 20:36:49,063 DEBUG [set] in set fun, event is set ? True 2016-08-1420:36:49,063 DEBUG [worker] event is set
为什么会这样?
因为在测试代码中启动了两个线程分别调用worker和set函数,worker函数判断当event没有被set时打印类似这样日志in worker fun, event is set ? False。而set函数负责将线程内部的标志设置为true,即执行event.set()语句,它将唤醒所有线程并告知event的内部标志已为true,set函数只是sleep了1秒钟,调用woker函数的线程就执行了很多次了。此时执行worker函数的线程收到这个信号后执行到while not event.is_set()语句时,event.is_set()返回了true,所以整个while语句返回False,那while循环中的语句将被跳过,而去执行logging.debug('event is set')。
2016-08-14 21:45:26,326 DEBUG [set] in set fun, event is set ? True 2016-08-14 21:45:26,326 DEBUG [worker] in worker fun, event is set ? True 2016-08-1421:45:26,326 DEBUG [worker] event is set Process finished with exit code 0