当前位置:   article > 正文

python并发运行协程 asyncio.gather 和 asyncio.wait

python asyncio wait
同步有序,异步无序

技巧:
几乎所有的异步框架都将异步编程模型简化:一次只允许处理一个事件。故而有关异步的讨论几乎都集中在了单线程内。

  • 如果某事件处理程序需要长时间执行,所有其他部分都会被阻塞。
    所以,一旦采取异步编程,每个异步调用必须“足够小”,不能耗时太久。如何拆分异步任务成了难题。

0.协程理解:
一份详细的asyncio入门教程
[进阶]-Python3 异步编程详解(史上最全篇)

Future
future是一个数据结构,表示还未完成的工作结果。事件循环可以监视Future对象是否完成。从而允许应用的一部分等待另一部分完成一些工作。Future
获取Futrue里的结果
future表示还没有完成的工作结果。事件循环可以通过监视一个future对象的状态来指示它已经完成。future对象有几个状态:

  • Pending
  • Running
  • Done
  • Cancelled
    创建future的时候,task为pending,事件循环调用执行的时候当然就是running,调用完毕自然就是done,如果需要停止事件循环,就需要先把task取消,状态为cancel。

Task
task是Future的一个子类,它知道如何包装和管理一个协程的执行。任务所需的资源
可用时,事件循环会调度任务允许,并生成一个结果,从而可以由其他协程消费。

  • event_loop 事件循环:程序开启一个无限的循环,程序员会把一些函数注册到事件循环上。当满足事件发生的时候,调用相应的协程函数。

  • coroutine 协程:协程对象,指一个使用async关键字定义的函数,它的调用不会立即执行函数,而是会返回一个协程对象。协程对象需要注册到事件循环,由事件循环调用。

  • task 任务:一个协程对象就是一个原生可以挂起的函数,任务则是对协程进一步封装,其中包含任务的各种状态。

  • async/await 关键字:python3.5 用于定义协程的关键字,async定义一个协程,await用于挂起阻塞的异步调用接口。

  • 启动一个协程:

  1. import asyncio
  2. async def foo():
  3. print("这是一个协程")
  4. if __name__ == '__main__':
  5. loop = asyncio.get_event_loop()
  6. try:
  7. print("开始运行协程")
  8. coro = foo()
  9. print("进入事件循环")
  10. loop.run_until_complete(coro)
  11. finally:
  12. print("关闭事件循环")
  13. loop.close()

原文链接:https://blog.csdn.net/ronon77/article/details/84854402
————————————————

  • asyncio.gather 和asyncio.wait区别:

  • 在内部wait()使用一个set保存它创建的Task实例。因为set是无序的所以这也就是我们的任务不是顺序执行的原因。wait的返回值是一个元组,包括两个集合,分别表示已完成和未完成的任务。wait第二个参数为一个超时值
    达到这个超时时间后,未完成的任务状态变为pending,当程序退出时还有任务没有完成此时就会看到如下的错误提示。
    gather的使用

  • gather的作用和wait类似不同的是。
    1.gather任务无法取消
    2.返回值是一个结果列表
    3.可以按照传入参数的 顺序,顺序输出
    ———————————————

1.Aiohttp的ClientSession理解:

  • 你使用async
    以及await关键字将函数异步化。在hello()中实际上有两个异步操作:
    首先异步获取相应,然后异步读取响应的内容。

  • Aiohttp推荐使用ClientSession作为主要的接口发起请求。
    ClientSession允许在多个请求之间保存cookie以及相关对象信息。
    Session(会话)在使用完毕之后需要关闭,关闭Session是另一个异步操作,

  • 所以每次你都需要使用[async with]关键字。一旦你建立了客户端session,你可以用它发起请求。这里是又一个异步操作的开始。

  • 上下文管理器的with语句可以保证在处理session的时候,总是能正确的关闭它。
    要让你的程序正常的跑起来,你需要将他们加入事件循环中。
    所以你需要创建一个asyncio loop的实例, 然后将任务加入其中

  1. 例子:
  1. import asyncio
  2. from asyncio import sleep
  3. import aiohttp
  4. async def get_page():
  5. async with aiohttp.ClientSession() as session:
  6. # async with session.get('https://www.baidu.com') as resp:
  7. async with session.get('https://blog.csdn.net/u014595019/article/details/52295642') as resp:
  8. print(resp.status)
  9. print(await resp.text())
  10. await session.close()
  11. loop = asyncio.get_event_loop()
  12. # 执行多个函数任务队列
  13. tasks = [get_page(),sleep(5), get_page()]
  14. # asyncio.wait 并发协程
  15. loop.run_until_complete(asyncio.wait(tasks))
  16. # asyncio.gather 并发协程
  17. # loop.run_until_complete(asyncio.gather(tasks))
  18. # 执行单个函数
  19. # loop.run_until_complete(get_page())
  20. loop.close()

在用asyncio.wait 执行时, tasks任务队列里的sleep(5),不会报错,会异步执行等待5秒,程序就自然结束运行,
在asyncio.gather 执行sleep(5),报错:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/102698
推荐阅读
相关标签
  

闽ICP备14008679号