python中协程的用法

协程(Coroutine),也可以被称为微线程是一种用户态内的上下文切换技术。简而言之,其实就是通过一个线程实现代码块相互切换执行协程不是计算机提供,程序员人为创造。

实现协程有这么几种方法:

  • greenlet,早期模块。

  • yield关键字。

  • asyncio装饰器(py3.4)

  • async、await关键字(py3.5)【推荐】

1.1 greenlet实现协程

pip install greenlet 
from greenlet import greenlet


def func1():
    print(1)        # 第1步:输出 1
    gr2.switch()    # 第3步:切换到 func2 函数
    print(2)        # 第6步:输出 2
    gr2.switch()    # 第7步:切换到 func2 函数,从上一次执行的位置继续向后执行


def func2():
    print(3)        # 第4步:输出 3
    gr1.switch()    # 第5步:切换到 func1 函数,从上一次执行的位置继续向后执行
    print(4)        # 第8步:输出 4


gr1 = greenlet(func1)
gr2 = greenlet(func2)

gr1.switch() # 第1步:去执行 func1 函数

1.2 yield关键字

def func1():
    yield 1
    yield from func2()
    yield 2


def func2():
    yield 3
    yield 4


f1 = func1()
for item in f1:
    print(item)

1.3 asyncio

import asyncio

@asyncio.coroutine
def func1():
    print(1)
    # 网络IO请求:下载一张图片
    yield from asyncio.sleep(2)  # 遇到IO耗时操作,自动化切换到tasks中的其他任务
    print(2)


@asyncio.coroutine
def func2():
    print(3)
    # 网络IO请求:下载一张图片
    yield from asyncio.sleep(2) # 遇到IO耗时操作,自动化切换到tasks中的其他任务
    print(4)


tasks = [
    asyncio.ensure_future( func1() ),
    asyncio.ensure_future( func2() )
]

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

  注意:遇到IO阻塞自动切换

1.4 async & await关键字

  在python3.5及之后的关键字

import asyncio

async def func1():
    print(1)
    # 网络IO请求:下载一张图片
    await asyncio.sleep(2)  # 遇到IO耗时操作,自动化切换到tasks中的其他任务
    print(2)


async def func2():
    print(3)
    # 网络IO请求:下载一张图片
    await asyncio.sleep(2) # 遇到IO耗时操作,自动化切换到tasks中的其他任务
    print(4)


tasks = [
    asyncio.ensure_future( func1() ),
    asyncio.ensure_future( func2() )
]

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

 

协程函数,定义函数时候 async def 函数名

协程对象,执行 协程函数() 得到的协程对象。

async def func():
    pass

result = func()

  注意:执行协程函数创建协程对象,函数内部代码不会执行。

  如果想要运行协程函数内部代码,必须要将协程对象交给事件循环来处理。

import asyncio 

async def func():
    print("快来搞我吧!")

result = func()
 
# 事件循环 # loop = asyncio.get_event_loop() # loop.run_until_complete( result ) asyncio.run( result ) # python3.7

示例1:

import asyncio

async def func():
    print("来玩呀")
    response = await asyncio.sleep(2)
    print("结束",response)

asyncio.run( func() )

示例2:

import asyncio


async def others():
    print("start")
    await asyncio.sleep(2)
    print('end')
    return '返回值'


async def func():
    print("执行协程函数内部代码")

    # 遇到IO操作挂起当前协程(任务),等IO操作完成之后再继续往下执行。当前协程挂起时,事件循环可以去执行其他协程(任务)。
    response = await others()

    print("IO请求结束,结果为:", response)
    
asyncio.run( func() )

2.1 await  可等待的对象(协程对象、Future对象、Task对象 -> IO等待)

import asyncio


async def others():
    print("start")
    await asyncio.sleep(2)
    print('end')
    return '返回值'


async def func():
    print("执行协程函数内部代码")

    # 遇到IO操作挂起当前协程(任务),等IO操作完成之后再继续往下执行。当前协程挂起时,事件循环可以去执行其他协程(任务)。
    response1 = await others()
    print("IO请求结束,结果为:", response1)
    
    response2 = await others()
    print("IO请求结束,结果为:", response2)
    
asyncio.run( func() 

  await就是等待对象的值得到结果之后再继续向下走。

2.2 Task对象

在事件循环中添加多个任务的。

Tasks用于并发调度协程,通过asyncio.create_task(协程对象)的方式创建Task对象,这样可以让协程加入事件循环中等待被调度执行。除了使用 asyncio.create_task() 函数以外,还可以用低层级的 loop.create_task()ensure_future() 函数。不建议手动实例化 Task 对象。

注意:asyncio.create_task() 函数在 Python 3.7 中被加入。在 Python 3.7 之前,可以改用低层级的 asyncio.ensure_future() 函数。

 

posted on 2023-11-14 21:28  一先生94  阅读(281)  评论(0编辑  收藏  举报

导航