欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Python 的并发异步 IO (asyncio) 解读 - I. 并发程序介绍

最编程 2024-06-09 09:45:48
...

1.1 定义

协程不是系统级线程,很多时候协程被称为“轻量级线程”、“微线程”、“纤程(fiber)”等。简单来说可以认为协程是线程里不同的函数,这些函数之间可以相互快速切换。

协程和用户态线程非常接近,用户态线程之间的切换不需要陷入内核,但部分操作系统中用户态线程的切换需要内核态线程的辅助。

协程是编程语言(或者 lib)提供的特性(协程之间的切换方式与过程可以由编程人员确定),是用户态操作。协程适用于 IO 密集型的任务。常见提供原生协程支持的语言有:c++20、golang、python 等,其他语言以库的形式提供协程功能,比如 C++20 之前腾讯的 fiber 和 libco 等等。

1.2 分类 

协程有两种,一种无栈协程,python中以 asyncio 为代表, 一种有栈协程,python 中 以 gevent 为代表,本文主要讲解 asyncio 线程。

有栈线程

无栈线程

备注

例子:

lua thread

python gevent

C# yield return

C# async\await

python asyncio

是否拥有单独的上下文:

上下文包括寄存器、栈帧

局部变量保存位置:

无栈协程的局部变量保存在堆上,比如generator的数据成员。

优点:

1. 每个协程有单独的上下文,可以在任意的嵌套函数中任何地方挂起此协程。

2. 不需要编译器做语法支持,通过汇编指令即可实现

1. 不需要为每个协程保存单独的上下文,内存占用低。

2. 切换成本低,性能更高。

缺点:

1. 需要提前分配一定大小的堆内存保存每个协程上下文,所以会出现内存浪费或者栈溢出。

2. 上下文拷贝和切换成本高,性能低于无栈协程。

1. 需要编译器提供语义支持,比如C# yield return语法糖。

2. 只能在这个生成器内挂起此协程,无法在嵌套函数中挂起此协程。

3. 关键字有一定传染性,异步代码必须都有对应的关键字。作为对比,有栈协程只需要做对应的函数调用。

无栈协程无法在嵌套函数中挂起此协程,有栈协程由于是通过保存和切换上下文包括寄存器和执行栈实现,可以在协程函数的嵌套函数内部yield这个协程并唤醒。

推荐阅读