VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > python教程 >
  • python基础教程之Python3标准库:asyncio异步I/O、事件循环和并发工具(2)

前面的例子使用生成器函数而不是原生协程重新实现。

1.3 调度常规函数调用

除了管理协程和/O回调,asyncio事件循环还可以根据循环中保存的一个定时器值来调度常规函数调用。

1.3.1 迅速调度一个回调

如果回调的时间不重要,那么可以用callsoon()调度下一次循环迭代的调用。调用回调时,函数后面额外的位置参数会传入回调。要向回调传入关键字参数,可以使用functools模块的partial()。


  1. import asyncio
  2. import functools
  3.  
  4. def callback(arg, *, kwarg='default'):
  5. print('callback invoked with {} and {}'.format(arg, kwarg))
  6.  
  7. async def main(loop):
  8. print('registering callbacks')
  9. loop.call_soon(callback, 1)
  10. wrapped = functools.partial(callback, kwarg='not default')
  11. loop.call_soon(wrapped, 2)
  12.  
  13. await asyncio.sleep(0.1)
  14.  
  15. event_loop = asyncio.get_event_loop()
  16. try:
  17. print('entering event loop')
  18. event_loop.run_until_complete(main(event_loop))
  19. finally:
  20. print('closing event loop')
  21. event_loop.close()

回调会按其调度的顺序来调用。

1.3.2 用Delay调度回调

要将一个回调推迟到将来某个时间调用,可以使用call_later()。这个方法的第一个参数是推迟时间(单位为秒),第二个参数是回调。


  1. import asyncio
  2.  
  3. def callback(n):
  4. print('callback {} invoked'.format(n))
  5.  
  6. async def main(loop):
  7. print('registering callbacks')
  8. loop.call_later(0.2, callback, 1)
  9. loop.call_later(0.1, callback, 2)
  10. loop.call_soon(callback, 3)
  11.  
  12. await asyncio.sleep(0.4)
  13.  
  14. event_loop = asyncio.get_event_loop()
  15. try:
  16. print('entering event loop')
  17. event_loop.run_until_complete(main(event_loop))
  18. finally:
  19. print('closing event loop')
  20. event_loop.close()

在这个例子中,同一个回调函数调度了多次,每次提供了不同的参数。最后一个调用使用了call_soon(),这会在所有按时间调用的实例之前基于参数3来调用这个回调,由此可以看出“迅速”调用的延迟往往最小。

1.3.3 在指定时间内调度一个回调

还可以安排在指定时间内调度一个调用。实现这个目的的循环依赖于一个单调时钟,而不是墙上时钟时间,以确保“now”时间绝对不会逆转。要为一个调度回调选择时间,必须使用循环的time()方法从这个时钟的内部状态开始。


  1. import asyncio
  2. import time
  3.  
  4. def callback(n, loop):
  5. print('callback {} invoked at {}'.format(n, loop.time()))
  6.  
  7. async def main(loop):
  8. now = loop.time()
  9. print('clock time: {}'.format(time.time()))
  10. print('loop time: {}'.format(now))
  11.  
  12. print('registering callbacks')
  13. loop.call_at(now + 0.2, callback, 1, loop)
  14. loop.call_at(now + 0.1, callback, 2, loop)
  15. loop.call_soon(callback, 3, loop)
  16.  
  17. await asyncio.sleep(1)
  18.  
  19. event_loop = asyncio.get_event_loop()
  20. try:
  21. print('entering event loop')
  22. event_loop.run_until_complete(main(event_loop))
  23. finally:
  24. print('closing event loop')
  25. event_loop.close()

需要注意,循环的时间与time.time()返回的值并不一致。

1.4 异步的生成结果

Future表示还未完成的工作的结果。事件循环可以通过监视一个Future对象的状态来指示它已经完成,从而允许应用的一部分等待另一部分完成一些工作。

1.4.1 等待future

Future的做法类似于协程,所以等待协程所用的技术同样可以用于等待future被标记为完成。下面的例子将future传递到事件循环的run_until_complete()方法。


  1. import asyncio
  2.  
  3. def mark_done(future, result):
  4. print('setting future result to {!r}'.format(result))
  5. future.set_result(result)
  6.  
  7. event_loop = asyncio.get_event_loop()
  8. try:
  9. all_done =
相关教程