【语法进阶】gevent的使用与总结
greenlet已经实现了协程,但是这个还要人工切换,
这里介绍一个比greenlet更强大而且能够自动切换任务的第三方库,那就是gevent。
安装第三方库
python -m pip install gevent
gevent:遇到IO操作时,会进行自动切换,属于主动式切换
注意:文件命名不要和第三方模块或内置模块重名
使用
gevent. spawn (函数名):创建协程对象
gevent. sleep(): 耗时操作
gevent. join(): 阻塞,等待某个协程执行结束
gevent. joinall(): 等待所有协程对象都执行结束再退出,参数是一个协程对象列表
import gevent
import time
def sing():print('在唱歌')gevent.sleep(2)print('唱完了')
def dance():print('在跳舞')gevent.sleep(2)print('跳完了')
if __name__ == '__main__':#1. 创建协程对象g1 = gevent.spawn(sing)g2 = gevent.spawn(dance)#2.阻塞,等待协程执行结束g1.join() #等待对象执行结束g2.join()
joinall()的使用
import gevent
def sing(name):for i in range(3):print(f'{name}在唱歌,被送走的第{i}次')if __name__ == '__main__':gevent.joinall([gevent.spawn(sing,'lalala'),gevent.spawn(sing,'hahaha')])
#joinall():等待所有的协程都执行结束再退出
monket补丁
monket补丁:拥有在模块运行时替换的功能
#导入模块
import time
import gevent
from gevent import monkeymonkey.patch_all() #将用到的time.sleep()代码替换成gevent里面自己实现耗时操作的gevent.sleep()代码
#注意:monkey.patch_all()必须放在被打补丁者的前面def sing(name):for i in range(3):time.sleep(2)print(f'{name}在唱歌,被送走的第{i}次')if __name__ == '__main__':gevent.joinall([gevent.spawn(sing,'lalala'),gevent.spawn(sing,'hahaha')])
总结
1线程是CPU调度的基本单位,进程是资源分配的基本单位
2进程、线程和协程对比
进程:切换需要的资源最大,效率最低
线程:切换需要的资源一般,效率一般
协程:切换需要的资源最小,效率高
3.多线程适合IO密集型操作(文件操作、爬虫),多进程适合CPU密集型操作(科学及计算、对视频进行高清解码、计算圆周率
进程、线程、协程都是可以完成多任务的,可以根据自己实际开发的需要选择使用。