一个解决方案(与轮询)将做每个Event
顺序等待一个循环
def wait_for_either(a, b):
while True:
if a.wait(tunable_timeout):
break
if b.wait(tunable_timeout):
break
我认为,如果您调整超时不够好,效果也OK。
最好的非投票我能想到的是在不同的线程等待每一个,并设置一个共享Event
的人,你会在主线程等待后。
def repeat_trigger(waiter, trigger):
waiter.wait()
trigger.set()
def wait_for_either(a, b):
trigger = threading.Event()
ta = threading.Thread(target=repeat_trigger, args=(a, trigger))
tb = threading.Thread(target=repeat_trigger, args=(b, trigger))
ta.start()
tb.start()
# Now do the union waiting
trigger.wait()
非常有趣,所以我写了以前的解决方案的OOP版本:
class EventUnion(object):
"""Register Event objects and wait for release when any of them is set"""
def __init__(self, ev_list=None):
self._trigger = Event()
if ev_list:
# Make a list of threads, one for each Event
self._t_list = [
Thread(target=self._triggerer, args=(ev,))
for ev in ev_list
]
else:
self._t_list = []
def register(self, ev):
"""Register a new Event"""
self._t_list.append(Thread(target=self._triggerer, args=(ev,)))
def wait(self, timeout=None):
"""Start waiting until any one of the registred Event is set"""
# Start all the threads
map(lambda t: t.start(), self._t_list)
# Now do the union waiting
return self._trigger.wait(timeout)
def _triggerer(self, ev):
ev.wait()
self._trigger.set()
是否有充分的理由使用2个不同的事件而不使用同一个事件? –
@Iulius你有一个单线程,你想成为事件驱动,但有2个队列...所以你需要醒来,当任何时候得到一个项目 – pyInTheSky
我很惊讶Python没有这个内置的。 –