定时调度常规函数
除了管理协程和I/O回调,asyncio事件循环还可以基于循环中的时间计数器值来调度常规函数。
计划调度“Soon”
如果回调的时间无关紧要,call_soon()函数可以被用来调度函数执行,函数之后的任何额外的参数都会被传递给被调用的函数。为了将关键字参数传递给回调函数,我们是用functools模块的 partial()函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import asyncio import functools def callback(arg, *, kwarg='default'): print('callback invoked with {} and {}'.format(arg, kwarg)) async def main(loop): print('registering callbacks') loop.call_soon(callback, 1) wrapped = functools.partial(callback, kwarg='not default') loop.call_soon(wrapped, 2) await asyncio.sleep(0.1) event_loop = asyncio.get_event_loop() try: print('entering event loop') event_loop.run_until_complete(main(event_loop)) finally: print('closing event loop') event_loop.close()
|
这种回调是按照预定的顺序调用的。
1 2 3 4 5 6 7
| $ python3 asyncio_call_soon.py entering event loop registering callbacks callback invoked with 1 and default callback invoked with 2 and not default closing event loop
|
延迟调度
将一个回调延迟到未来某个时间可以使用call_later()函数。第一个参数是要延迟的时间秒数,第二个参数是要回调的函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import asyncio def callback(n): print('callback {} invoked'.format(n)) async def main(loop): print('registering callbacks') loop.call_later(0.2, callback, 1) loop.call_later(0.1, callback, 2) loop.call_soon(callback, 3) await asyncio.sleep(0.4) event_loop = asyncio.get_event_loop() try: print('entering event loop') event_loop.run_until_complete(main(event_loop)) finally: print('closing event loop') event_loop.close()
|
在这个例子中,同样的回调函数通过不同的参数在不同的时间被调度。最后使用的call_soon()函数却在前面调度运行,表明“soon”是马上进行调度运行的。
1 2 3 4 5 6 7 8
| $ python3 asyncio_call_later.py entering event loop registering callbacks callback 3 invoked callback 2 invoked callback 1 invoked closing event loop
|
特定时间调度
还可以在一个特定的时间点进行调度。事件循环使用的是一个monotonic clock而不是一个wall-clock时间,以确保“now”的值永远不会倒退。要在特定的时间进行调度必须从循环的内部时间“now()”开始。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| def callback(n, loop): print('callback {} invoked at {}'.format(n, loop.time())) async def main(loop): now = loop.time() print('clock time: {}'.format(time.time())) print('loop time: {}'.format(now)) print('registering callbacks') loop.call_at(now + 0.2, callback, 1, loop) loop.call_at(now + 0.1, callback, 2, loop) loop.call_soon(callback, 3, loop) await asyncio.sleep(1) event_loop = asyncio.get_event_loop() try: print('entering event loop') event_loop.run_until_complete(main(event_loop)) finally: print('closing event loop') event_loop.close()
|
注意,调度的时间是根据循环内部的时间而不是当前的时间time.time()。
1 2 3 4 5 6 7 8 9 10
| $ python3 asyncio_call_at.py entering event loop clock time: 1479050248.66192 loop time: 1008846.13856885 registering callbacks callback 3 invoked at 1008846.13867956 callback 2 invoked at 1008846.239931555 callback 1 invoked at 1008846.343480996 closing event loop
|
本文翻译自《The Python3 Standard Library By Example》asyncio相关章节