# Python学习--协程--asyncio

530 阅读3分钟

简介

协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。

协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

本人也是刚刚开始学习Python,难免有错误与疏漏还望多多指正~(づ ̄3 ̄)づ╭❤~

知乎上关于协程的一个问题~

语法

协程函数

在函数前加async前缀,则表示该函数为协程函数~

import asyncio

async def coroutine(i): pass

这样 **coroutine(1)**则不再是调用函数,而是返回一个协程对象

判断一个对象是否为协程对象,返回 布尔值~

asyncio.iscoroutine(coroutine(1))

确保对象为协程对象,若是协程对象则返回,若不是则抛出错误~

ob = asyncio.ensure_future(coroutine(1))

事件循环

我的理解是这样的~ asyncio通过运行循环来接受事件,进行统一调度,以实现协程的效果~

loop = asyncio.get_event_loop()         #创建循环

loop.run_until_complete(coroutine(1))   #添加协程

这样 协程对象就进行执行了~

协程效果实现

协程要实现的效果之一,就是要实现函数的有序执行~ 当一个函数执行完后,再去执行下面的函数~ 通过await

import asyncio

#协程1
async def coroutine(i):
    print("协程执行 %s" % i)
    res = await someFunction()
    print("协程%s 返回功能为 %s" % (,res))

#协程2
async def someFunction():
    print("运行部分功能")
    await asyncio.sleep(1) #休息1s 模拟耗时操作
    return "功能结果"


loop = asyncio.get_event_loop()         #创建循环

loop.run_until_complete(coroutine(1))   #执行任务

执行结果如下

协程执行 1
运行部分功能
返回功能为 功能结果

回调

当协程方法执行完毕后进行回调~

import asyncio

#协程1
async def coroutine(i):
    print("协程执行 %s" % i)
    
#回调
def callbackFunc(po):
    print('执行回调~ ')
    
loop = asyncio.get_event_loop()         #创建循环

ob = asyncio.ensure_future(coroutine(1))

ob.add_done_callback(callbackFunc)

loop.run_until_complete(ob)     

运行结果如下,作为回调的函数,需要接受一个传入参数(回调该函数的协程对象~),

协程执行 1
执行回调~ 

多协程对象并发执行~

效果就和多线程并发执行一样~ 下面是示例代码~

import asyncio

#协程1
async def coroutine(i):
    print("协程执行 %s" % i)
    res = await someFunction()
    print("协程%s 返回功能为 %s" % (i,res))

#协程2
async def someFunction():
    print("运行部分功能")
    await asyncio.sleep(1) #休息1s 模拟耗时操作
    return "功能结果"


loop = asyncio.get_event_loop()         #创建循环

coArr = [coroutine(1),coroutine(2),coroutine(3)]

ob = asyncio.gather(*coArr)

loop.run_until_complete(ob)   #执行任务

运行效果如下~~~

协程执行 3
运行部分功能
协程执行 2
运行部分功能
协程执行 1
运行部分功能
协程3 返回功能为 功能结果
协程2 返回功能为 功能结果
协程1 返回功能为 功能结果

结束

结语

本文,是本人对Python学习的内容总结~ 由于初学 难免有遗漏错误,还望多多指正~