多任务之协程浅谈
一、协程(Coroutine)
1、认识协程
a>协程,又称为微线程、纤程
b>协程是Python中另外一种实现多任务的方式,比线程占用更小的执行单位
c>最通俗的理解:就是一个可以暂停的函数,可以挂起的函数
d>通过yield生成器可以实现协程
2、协程和线程的差异
线程包含在进程中, 协程包含在线程中,一个线程可以包含多个协程,协程的切换开销比线程更小,协程在切换时,不需要保存和恢复线程的状态并发量更高
3、使用yield生成器实现协程
二、协程-greenlet
1、greenlet介绍:是Python中的一个模块,是对yield生成器的封装,可更简便实现协程
2、安装方式及使用
安装greenlet模块
sudo pip3 install greenlet
好比 sudo apt-get install packagename
-pip3:安装Python3中的模块Linux命令
-pip: 安装Python2中模块Linux命令
-使用
import greenlet
创建greenlet对象
g1 = greenlet.greenlet(task):task:要执行的函数名
g1.switch():执行greenlet
实例:有两个任务,一个不断打印A,一个不断打印B,通过greenlet实现多任务协程
参考代码如下:
五、协程-gevent
1、使用greenlet的不足:
1、有多个任务的情况下,人工切换协程非常麻烦
2、在耗时操作的时候切换协程,耗时操作有很多种
2、gevent使用原理:
1、gevent是对greenlet再一次封装
2、原理是当一个greenlet遇到O(指的是I/O输入输出操作,比如网络、文件访问等)操作时,就自动切换到其他的greenlet,等到O操作完成,再在适当的时候切换回来继续执行。
3、由于IO操作非常耗时,经常使程序出于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO
3、gevent的使用
1、安装gevent模块
sudo pip3 install gevent
2、使用
import gevent
g1 = gevent.spawn(task) 创建gevent对象,task是任务函数名
g1.join() 执行gevent对象
使用gevent实现多任务参考代码:
4、gevent写法的优化
a>简化写法:
通过一行代码执行所有的协程
gevent.joinall([gevent.spawn(task1, 3),gevent.spawn(task2, 3)])
b>给gevent打补丁
from gevent import monkey
monkey.patch_all() 打补丁
参考代码如下:
六、进程、线程、协程的区别
进程是操作系统资源分配的单位
线程是CPU调度的单位
进程切换需要的资源最大,效率低
线程切换需要的资源一般,效率一般 (当然在不考虑GIL情况下)
协程切换需要的资源最小,效率高
多任务进程、多线程根据CPU核数不一样可能是并行的,但是协程是在一个线程中,所以是并发 一般开发中:使用多进程(一般是CPU的核数)+ 多协程