Event&Condition pyton

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 对象来替代

公众号请关注:侠之大者
原文地址:https://www.cnblogs.com/kamil/p/5311704.html