Python 协程和asyncio模块

本文首先对asyncio模块的使用进行简单的介绍,然后着重分析asyncio中关于事件循环和协程的部分,而对于模块中在事件循环创建套接字连接等方法将会在另外的文章介绍


简单使用

        async def语句或使用@asyncio.coroutine装饰的生成器来实现可以使用asyncio模块的协程

         基于生成器的协程应该使用yield from 而不是原始的yield语法

import asyncio

@asyncio.coroutine        
def hello():
    print("Hello world!")
    r = yield from asyncio.sleep(1)    #asyncio.sleep(1)是一个协程,在这里可以看成一个耗时1秒的IO操作
    print("Hello again!")

loop = asyncio.get_event_loop()    #获取当前上下文的事件循环对象
loop.run_until_complete(hello())    #运行事件循环,等待协程完成
loop.close()                       #关闭事件循环

            @asyncio.coroutine装饰器把一个生成器函数标记为协程函数

            yield from 等待asyncio.sleep(1)协程的完成,在此期间,主线程并未等待,而是去执行事件循环中其他可以执行的协程,因此可以实现并发执行。


在Python3.5中加入了新的语法async/await,分别用于替换@asyncio.coroutine和yield from

        需要注意@asyncio.coroutine/yield from 和async/await两种方式不能混用


        可以在在事件循环中执行多个协程

tasks = [hello(), hello()]
loop.run_until_complete(asyncio.wait(tasks))


协程Coroutine

名词解释

    首先我们区分一下,将yield语句放置在赋值符号右边的生成器可以被称为协程,而使用async def定义 或@asyncio.coroutine修饰的函数也可以称为协程,但是后者是可以使用asyncio模块的Coroutine协程类型

    同样"协程"一词可以用来指协程函数和协程对象。

            协程函数 就是使用async def或用@asyncio.coroutine装饰的函数,可以使用asyncio.iscoroutinefunction(func)来判断

            协程对象 就是通过调用协程函数获得的对象,可以使用asyncio.iscoroutine(obj)来判断

协程函数中通常由两种方式来结束执行

                return expression      为通过await或yield from生成结果

                raise expression        生成异常


        在事件循环中轮询的对象都是Future对象,Task为Future的子类,也可在事件循环中,通常Future和Task没有什么本质区别,可以混用

        Future对象是指添加到事件循环中,将要通过执行来生成结果或抛出异常的对象

Future对象在事件事件循环中通常由两种方式出现

                使用在result = await/yield from future表达式中,挂起当前协程等待future完成,返回future结果或抛出异常,这两个都能传播

                                如果future被取消(future.canael()),那么抛出asyncio.CanceledError异常

                使用loop.create_task()或asyncio.ensure_future()或loop.create_future()将future注册到事件循环中

                这个两个可以联合使用 result = await asyncio.ensure_future(cor),将coroutine转换为future对象,注册到事件循环,然后再挂起当前的协程,等待future完成返回结果

           

Coroutine对象以两种方式启动

                调用协程并不会启动其代码运行,调用返回的协程对象在安排运行之前不会执行任何操作


            使用在result = await/yield from coroutine表达式中,当前协程等待另一个协程返回生产结果或抛出异常

     

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值