python3.7中asyncio的具体实现

匿名 (未验证) 提交于 2019-12-02 22:11:45

讲讲我在使用python异步IO语法时踩过的坑

简单介绍异步IO的原理

以及利用最新语法糖实现异步IO的步骤,

然后给出实现异步的不同例子

网上找了很多python的asyncio示例.很多都是用

# 获取EventLoop: loop = asyncio.get_event_loop() # 执行coroutine loop.run_until_complete(hello()) loop.close()

通过create_future向里面添加task的方法来进行异步IO调用.

asyncio.run() asyncio.create_task() asyncio.gather()

下面通过实例具体分析asyncio异步的原理和使用方法

async def foo():     print('----start foo')     await asyncio.sleep(1)     print('----end foo')/*预期想要的结果----start foo(等待一秒)----end foo*/

async是旧版本装饰器的语法糖

(异步环境是我自己创造的为了理解异步操作发明的词汇)

开启这个异步环境的标志是

asyncio.run(foo())

async def foo():     print('start foo')     await asyncio.sleep(1)     print('----end foo')  if __name__ == '__main__':     asyncio.run(foo())

执行以下之后发现结果没问题

def foo2():     print('----start foo')     time.sleep(1)     print('----end foo')  def bar2():     print('----start bar')     time.sleep(2)     print('----end bar')  if __name__ == '__main__':     foo2()     bar2()  /* 预期输出: ----start foo (等待1秒) ----end foo ----start bar (等待2秒) ----end bar */

把上面的函数改写成异步之后

async def foo():     print('----start foo')     await asyncio.sleep(1)     print('----end foo')  async def bar():     print('****start bar')     await asyncio.sleep(2)     print('****end bar')  async def main():     await foo()     await bar()  if __name__ == '__main__':     asyncio.run(main())

我们想要的结果是

----start foo

****start bar

(等待1秒)

----end foo

(等待1秒)

****end bar

----start foo

(等待1秒)

----end foo

****start bar

(等待2秒)

****end bar

这是为什么呢

那么如何一起执行呢

基本的有两种方法

1.采用函数gather

官方文档中的解释是

asyncio.gather(*awsloop=Nonereturn_exceptions=False)

并发aws可等待对象

aws

aws

return_exceptionsFalsegather()aws不会被取消

return_exceptionsTrue,异常会和成功的结果一样处理,并聚合至结果列表。

gather()被取消被取消

aws被取消CancelledErrorgather()不会

因此代码就有了

async def foo():     print('----start foo')     await asyncio.sleep(1)     print('----end foo')  async def bar():     print('****start bar')     await asyncio.sleep(2)     print('****end bar')  async def main():     res = await asyncio.gather(foo(), bar())     print(res)  if __name__ == '__main__':     asyncio.run(main())

asyncio.create_task(coro)

coro协程Task

get_running_loop()RuntimeError

在 Python 3.7 中被加入asyncio.ensure_future()

async def foo():     print('----start foo')     await asyncio.sleep(1)     print('----end foo')  async def bar():     print('****start bar')     await asyncio.sleep(2)     print('****end bar')  async def main():     asyncio.create_task(foo())     asyncio.create_task(bar())  if __name__ == '__main__':     asyncio.run(main())

----start foo
****start bar

因此需要等待它们执行完毕.

最后的代码为

async def foo():     print('----start foo')     await asyncio.sleep(1)     print('----end foo')  async def bar():     print('****start bar')     await asyncio.sleep(2)     print('****end bar')  async def main():     task1 = asyncio.create_task(foo())     task2 = asyncio.create_task(bar())      await task1     await task2  if __name__ == '__main__':     asyncio.run(main())

如果有多个请求

async def foo():     print('----start foo')     await asyncio.sleep(1)     print('----end foo')  async def main():     tasks = []     for i in range(10):         tasks.append(asyncio.create_task(foo()))     await asyncio.wait(tasks)  if __name__ == '__main__':     asyncio.run(main())

async def foo():     print('----start foo')     await asyncio.sleep(1)     print('----end foo')  async def bar():     print('****start bar')     await asyncio.sleep(2)     print('****end bar')  async def main():     tasks = []     for i in range(10):         tasks.append(asyncio.create_task(foo()))     for j in range(10):         tasks.append(asyncio.create_task(bar()))     await asyncio.wait(tasks)  if __name__ == '__main__':     asyncio.run(main())

异步嵌套

async def foo():     print('----start foo')     await asyncio.sleep(1)     print('----end foo')  async def bar():     print('****start bar')     await asyncio.sleep(2)     print('****end bar')  async def foos():     print('----------------------')     tasks = []     for i in range(3):         tasks.append(asyncio.create_task(foo()))     await asyncio.wait(tasks)  async def main():     tasks = []     for i in range(3):         tasks.append(asyncio.create_task(foos()))     for j in range(3):         tasks.append(asyncio.create_task(bar()))     await asyncio.wait(tasks)  if __name__ == '__main__':     asyncio.run(main())

async def foo():     print('----start foo')     await asyncio.sleep(1)     print('----end foo')  async def foos():     print('----------------------')     tasks = []     await foo()     await foo()     await foo()  async def main():     tasks = []     for i in range(3):         tasks.append(asyncio.create_task(foos()))     await asyncio.wait(tasks)  if __name__ == '__main__':     asyncio.run(main())

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!