python asyncio.sleep_python – 中断当前正在执行的所有asyncio.sleep

哪里

这是在Linux,Python 3.5.1上.

什么

我正在使用asyncio开发一个监视进程,它在各个地方的任务等待各种持续时间的asyncio.sleep调用.

有一些时间点,我希望能够中断所有说的asyncio.sleep调用并让所有任务正常进行,但我找不到如何做到这一点.一个示例是正常关闭监视器进程.

如何(失败的假设)

我以为我可以发送一个ALRM信号,但过程就会消失.我尝试用以下方法捕获ALRM信号:

def sigalrm_sent(signum, frame):

tse.logger.info("got SIGALRM")

signal.signal(signal.SIGALRM, sigalrm_sent)

然后我得到关于捕获SIGALRM的日志行,但是asyncio.sleep调用没有被中断.

如何(kludge)

此时,我通过调用此协程替换了所有asyncio.sleep调用:

async def interruptible_sleep(seconds):

while seconds > 0 and not tse.stop_requested:

duration = min(seconds, tse.TIME_QUANTUM)

await asyncio.sleep(duration)

seconds -= duration

所以我只需选择一个不太小也不太大的TIME_QUANTUM.

有没有办法打断所有正在运行的asyncio.sleep调用,我错过了它?

解决方法:

中断asyncio.sleep的所有正在运行的调用似乎有点危险,因为它可以在代码的其他部分中使用,用于其他目的.相反,我会制作一个专用的睡眠协程来跟踪其正在运行的呼叫.然后可以通过取消相应的任务来中断它们:

def make_sleep():

async def sleep(delay, result=None, *, loop=None):

coro = asyncio.sleep(delay, result=result, loop=loop)

task = asyncio.ensure_future(coro)

sleep.tasks.add(task)

try:

return await task

except asyncio.CancelledError:

return result

finally:

sleep.tasks.remove(task)

sleep.tasks = set()

sleep.cancel_all = lambda: sum(task.cancel() for task in sleep.tasks)

return sleep

例:

async def main(sleep, loop):

for i in range(10):

loop.create_task(sleep(i))

await sleep(3)

nb_cancelled = sleep.cancel_all()

await asyncio.wait(sleep.tasks)

return nb_cancelled

sleep = make_sleep()

loop = asyncio.get_event_loop()

result = loop.run_until_complete(main(sleep, loop))

print(result) # Print '6'

出于调试目的,loop.time = lambda:float(‘inf’)也可以.

标签:python,linux,async-await,python-asyncio