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

本站最新发布   Python从入门到精通|Python基础教程
试听地址  
https://www.xin3721.com/eschool/pythonxin3721/


async def main(num_phases):
  • print('starting main')
  • phases = [
  • phase(i)
  • for i in range(num_phases)
  • ]
  • print('waiting for phases to complete')
  • completed, pending = await asyncio.wait(phases)
  • results = [t.result() for t in completed]
  • print('results: {!r}'.format(results))
  •  
  • event_loop = asyncio.get_event_loop()
  • try:
  • event_loop.run_until_complete(main(3))
  • finally:
  • event_loop.close()
  • 在内部,wait()使用一个set来保存它创建的Task实例,这说明这些实例会按一种不可预知的顺序启动和完成。wait()的返回值是一个元组,包括两个集合,分别包括已完成和未完成的任务。

    如果使用wait()时提供了一个超时值,那么达到这个超时时间后,将只保留未完成的操作。 

    
    
    1. import asyncio
    2.  
    3. async def phase(i):
    4. print('in phase {}'.format(i))
    5. try:
    6. await asyncio.sleep(0.1 * i)
    7. except asyncio.CancelledError:
    8. print('phase {} canceled'.format(i))
    9. raise
    10. else:
    11. print('done with phase {}'.format(i))
    12. return 'phase {} result'.format(i)
    13.  
    14. async def main(num_phases):
    15. print('starting main')
    16. phases = [
    17. phase(i)
    18. for i in range(num_phases)
    19. ]
    20. print('waiting 0.1 for phases to complete')
    21. completed, pending = await asyncio.wait(phases, timeout=0.1)
    22. print('{} completed and {} pending'.format(
    23. len(completed), len(pending),
    24. ))
    25. # Cancel remaining tasks so they do not generate errors
    26. # as we exit without finishing them.
    27. if pending:
    28. print('canceling tasks')
    29. for t in pending:
    30. t.cancel()
    31. print('exiting main')
    32.  
    33. event_loop = asyncio.get_event_loop()
    34. try:
    35. event_loop.run_until_complete(main(3))
    36. finally:
    37. event_loop.close()

    其余的后台操作要显式地处理,这有多方面的原因。尽管wait()返回时未完成的任务是挂起的,但只要控制返回到事件循环它们就会恢复运行。如果没有另一个wait()调用,则将没有对象接收任务的输出;也就是说,任务会运行并消费资源,但不会带来任何好处。另外,如果程序退出时还有未完成的任务,那么asyncio会发出一个警告。这些警告可能打印到控制台上,应用的用户便会看到。因此,最好取消所有剩余的后台操作,或者使用wait()让它们结束运行。

    1.6.2 从协程收集结果

    如果后台阶段是明确的,而且这些阶段的结果很重要,那么gather()可能对等待多个操作很有用。 

    
    
    1. import asyncio
    2.  
    3. async def phase1():
    4. print('in phase1')
    5. await asyncio.sleep(2)
    6. print('done with phase1')
    7. return 'phase1 result'
    8.  
    9. async def phase2():
    10. print('in phase2')
    11. await asyncio.sleep(1)
    12. print('done with phase2')
    13. return 'phase2 result'
    14.  
    15. async def main():
    16. print('starting main')
    17. print('waiting for phases to complete')
    18. results = await asyncio.gather(
    19. phase1(),
    20. phase2(),
    21. )
    22. print('results: {!r}'.format(results))
    23.  
    24. event_loop = asyncio.get_event_loop()
    25. try:
    26. event_loop.run_until_complete(main())
    27. finally:
    28. event_loop.close()

    gather()创建的任务不会对外提供,所以无法将其取消。返回值是一个结果列表,结果的顺序与传入gather()的参数顺序相同,而不论后台操作实际上是按什么顺序完成的。

    1.6.3 后台操作完成时进行处理

    as_completed()是一个生成器,会管理指定的一个协程列表,并生成它们的结果,每个协程结束运行时一次生成一个结果。与wait()类似,as_completed()不能保证顺序,不过执行其他动作之前没有必要等待所有后台操作完成。

    
    
    1. import
    相关教程