Python协程 & 异步编程(asyncio) 入门介绍

时间:2025-03-11 07:37:12

本文首发于:行者AI

在近期的编码工作过程中遇到了async和await装饰的函数,查询资料后了解到这种函数是基于协程的异步函数。这类编程方式称为异步编程,常用在IO较频繁的系统中,如:Tornado web框架、文件下载、网络爬虫等应用。协程能够在IO等待时间就去切换执行其他任务,当IO操作结束后再自动回调,那么就会大大节省资源并提供性能。接下来便简单的讲解一下异步编程相关概念以及案例演示。

1. 协程简介

1.1 协程的含义及实现方法

协程(Coroutine),也可以被称为微线程,是一种用户态内的上下文切换技术。简而言之,其实就是通过一个线程实现代码块相互切换执行。例如:

def func1():
	print(1)
    ...   # 协程介入
	print(2)
	
def func2():
	print(3)
    ...   # 协程介入
	print(4)

func1()
func2()

上述代码是普通的函数定义和执行,按流程分别执行两个函数中的代码,并先后会输出:1、2、3、4。但如果介入协程技术那么就可以实现函数见代码切换执行,最终输入:1、3、2、4

在Python中有多种方式可以实现协程,例如:

  • greenlet,是一个第三方模块,用于实现协程代码(Gevent协程就是基于greenlet实现);

  • yield,生成器,借助生成器的特点也可以实现协程代码;

  • asyncio,在Python3.4中引入的模块用于编写协程代码;

  • async & awiat,在Python3.5中引入的两个关键字,结合asyncio模块可以更方便的编写协程代码。

前两种实现方式较为老旧,所以重点关注后面的方式

标准库实现方法

asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。

import asyncio

@asyncio.coroutine
def func1():
    print(1)
    yield from asyncio.sleep(2)  # 遇到IO耗时操作,自动化切换到tasks中的其他任务
    print(2)

@asyncio.coroutine
def func2():
    print(3)
    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))

关键字实现方法

async & await关键字在Python3.5版本中正式引入,代替了 装饰器,基于他编写的协程代码其实就是上一示例的加强版,让代码可以更加简便可读。


import asyncio

async def func1():
    print(1)
    await asyncio.sleep(2)  # 耗时操作  
    print(2