本文主要为大家详细介绍了python进阶之协程,文中示例代码介绍的非常详细,具有一定的参考价值。
协程(Coroutine
),又称微线程,纤程。(协程是一种用户态的轻量级线程)
作用:在执行 A 函数的时候,可以随时中断,去执行 B 函数,然后中断B函数,继续执行 A 函数 (可以自动切换),但这一过程并不是函数调用(没有调用语句),过程很像多线程,然而协程只有一个线程在执行
通俗的理解:在一个线程中的某个函数,可以在任何地方保存当前函数的一些临时变量等信息,然后切换到另外一个函数中执行,注意不是通过调用函数的方式做到的,并且切换的次数以及什么时候再切换到原来的函数都由开发者自己确定
协程和线程差异
在实现多任务时, 线程切换从系统层面远不止保存和恢复 CPU上下文这么简单。 操作系统为了程序运行的高效性每个线程都有自己缓存Cache等等数据,操作系统还会帮你做这些数据的恢复操作。 所以线程的切换非常耗性能。但是协程的切换只是单纯的操作CPU的上下文
,所以一秒钟切换个上百万次系统都抗的住。
协程的标准
必须在只有一个单线程里实现并发
- 修改共享数据不需加锁
- 用户程序里自己保存多个控制流的上下文栈
- 一个协程遇到 IO 操作自动切换到其它协程
协程的优点
- 由于自身带有上下文和栈,无需线程上下文切换的开销,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级
- 无需原子操作的锁定及同步的开销
- 方便切换控制流,简化编程模型
- 单线程内就可以实现并发的效果,最大限度地利用 cpu,且可扩展性高,成本低
协程的缺点
- 无法利用多核资源:协程的本质是个单线程,它不能同时将 单个 CPU 的多个核用上,协程需要和进程配合才能运行在多 CPU 上
- 进行阻塞(Blocking)操作(如 IO 时)会阻塞掉整个程序
- 计算型的操作,利用协程来回切换执行,没有任何意义,来回切换并保存状态 反倒会降低性能。
python中实现协程的方式
greenlet
,是一个第三方模块,用于实现协程代码(Gevent协程就是基于greenlet实现)yield
,生成器,借助生成器的特点也可以实现协程代码。asyncio
,在Python3.4中引入的模块用于编写协程代码。async & awiat
,在Python3.5中引入的两个关键字,结合asyncio
模块可以更方便的编写协程代码(推荐)。
async&await关键字
协程实现的方式有多种,目前最流行的方式就是async&await
,其他的方式了解即可,本文就介绍最流行的一种方式
使用协程需要了解2个,事件循环和定义协程函数