python异步方法asyncio的使用2

因为这里会说道awaitable对象,我们了解下什么是awaitable,awaitable对象可以理解为可暂停等待的对象,有三类对象是可以等待的,即coroutines, Tasks,Futures.
coroutine:本质是一个函数,@asyncio.coroutine装饰器标记一个generator为coroutine类型,然后在generator内部用yield from调用另一个coroutine实现异步操作,这里我们不多做说明
Tasks:任务,顾名思义,就是要完成某件事情,Task用来 并发调度的协程,即对协程函数的进一步包装?那为什么还需要包装呢?因为单纯的协程函数仅仅是一个函数而已,将其包装成任务,任务是可以包含各种状态的,异步编程最重要的就是对异步操作状态的把控了。
Futures:它是一个较低层的概念,他代表一个一步操作的最终结果,因为一步操作一般用于耗时操作,结果不会立即得到,会在“将来”得到异步运行的结果,故而命名为Future,当一个Future对象被等待的时候,协程会一直等待,直到Future已经运算完毕。Future是Task的父类,一般情况下,已不用去管它们两者的详细区别,也没有必要去用Future,用Task就可以了.
这里说到了较低层的概念,那么我们说下asyncio的基本架构
**

asyncio的基本架构

**
asyncio分为高层API和低层API,我们都可以使用,我们前面所讲的Coroutine和Tasks属于高层API,而Event Loop 和Future属于低层API。当然asyncio所涉及到的功能远不止于此,我们只看这么多。下面是是高层API和低层API的概览:
高层API:

  • Coroutines 和 Tasks

  • Streams

  • Synchronization Primitives

  • Subprocesses

  • Queues

  • Exceptions
    低层API

  • Event Loop

  • Futures

  • Ttansports and Protocols

  • Policies

  • Platform Support

所谓的高层API主要是指能通过asyncio直接调用的方法,如asyncio.xxx()方法,常见的高层API有:
1.运行异步协程

  • 创建事件循环对象loop,即asyncio.get_event_loop(),然后通过事件循环运行协程函数,loop.run_until_complete(func_name)
  • 直接通过asyncio.run(func_name),但是run()函数是python3.7版本新添加的,前面的版本没有,并且,这个run()函数总是会新建一个事件循环,然后在运行结束后关闭事件循环,所以,如果同一个线程中已经有了一个事件循环,则不能使用这个函数
    2.创建任务
  • task = asyncio.ensure_future(func())
  • task = asyncio.create_task(func()) #注意,这是是python3.7版本中才有
    或者
    loop.create_future()
    loop.create_task(func)
    3.睡眠
await asyncio.sleep(delay, result=None)
这个函数表示的是:当前的那个任务(协程函数)睡眠多长时间,而允许其他任务执行。这是它与time.sleep()的区别,time.sleep()是当前线程休息,注意他们的区别哦。

另外如果提供了参数result,当当前任务(协程)结束的时候,它会返回
4.并发运行多个任务

await asyncio.gather(*coros_or_futures, loop=None, return_exceptions=False)
参数描述
*coros_or_futures多任务序列拆分操作
loop循环事件
return_exceptionsFalse:默认值,第一个出发异常的任务会立即返回,然后其他的任务继续执行,True:对于已经发生了异常的任务,也会像成功执行了任务那样,等到所有的任务执行结束一起将错误的结果返回到最终的结果列表里面。

当所有的任务都完成之后,返回的结果是一个列表的形式,列表中值的顺序和*coros_or_futures完成的顺序是一样的。
如果gather()本身被取消了,那么绑定在它里面的任务也就取消了
5.防止任务取消

await asyncio.shield(*args, *, loop=None)

它本身也是awaitable的。顾名思义,shield为屏蔽、保护的意思,即保护一个awaitable 对象防止取消,一般情况下不推荐使用,而且在使用的过程中,最好使用try语句块更好。
6.设置timeout

await asyncio.wait_for(aw, timeout, *, loop=None)

如果aw是一个协程函数,会自动包装成一个任务task,举个例子说明一下

import asyncio

async def default():
    print("来执行异步了")
    await asyncio.sleep(5000)
    print("异步执行完了")

async def main():
    try:
        print("小样,等你先跑3秒")
        await asyncio.wait_for(default(), timeout=3)
    except asyncio.TimeoutError:
        print("超时了")


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

运行结果:

小样,等你先跑3秒
来执行异步了
超时了

先创建循环事件对象loop,然后执行异步函数main(),打印第一句,然后执行default(),打印第二句,但是同时,default()函数通过wait_for()设置了超时时间3m,当打印完第二部的时候,沉睡了5000秒,等到设置的超时时间过后,报TimeoutError,并打印第三句,当异步操作需要执行的时间超过wait_for()设置的timeout,就会触发异常,所以在编写程序的时候,如果要给异步操作设置timeout,一定要选择合适,如果异步操作本身的耗时较长,而你设置的timeout太短,会涉及到她还没做完,就抛出异常了。
6.多个协程函数的等候

await asyncio.wait(aws, *, loop=None, timeout=None, return_when=ALL_COMPLETED)
参数描述
aws多个协程函数或者任务的一个集合
loop循环事件
timeout设置超时时间
return_when设置什么时候wait函数该返回值,值有如下几个:1.FIRST_COMPLETED,当任何一个 ask或者是future完成或者是取消,wait函数就返回. 2.FIRST_EXCEPTION,当任何一个task或者是future触发了某一个异常,就返回,.如果是所有的task和future都没有触发异常,则等价与下面的 ALL_COMPLETED. 3.ALL_COMPLETED, 当所有的task或者是future都完成或者是都取消的时候,再返回。

该函数的返回值是一个集合(done, pending) ,其中done是一个集合,表示已经完成的任务的tasks, penging也是一个集合,表示还没完成的任务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值