4、协程4.1 协程的概念
协程是也是实现多任务的一种方式协程,又称微线程,纤程,也称为用户级线程,在不开辟线程的基础上完成多任务,也就是在单线程的情况下完成多任务,多个任务按照一定顺序交替执行 通俗理解只要在def里面只看到一个yield关键字表示就是协程
协程yield的代码实现简单实现协程
import timedef work1:while True:print("----work1---")yieldtime.sleep(0.5)def work2:while True:print("----work2---")yieldtime.sleep(0.5)def main:w1 = work1w2 = work2while True:next(w1)next(w2)if __name__ == "__main__":main运行结果:----work1-------work2-------work1-------work2-------work1-------work2-------work1-------work2-------work1-------work2-------work1-------work2---...省略... 小结协程之间执行任务按照一定顺序交替执行
5、greenlet5.1 greentlet的介绍为了更好使用协程来完成多任务,Python中的greenlet模块对其封装,从而使得切换任务变的更加简单
使用如下命令安装greenlet模块:
pip3 install greenlet使用协程完成多任务import timeimport greenlet# 任务1def work1:for i in range(5):print("work1...")time.sleep(0.2)# 切换到协程2里面执行对应的任务g2.switch# 任务2def work2:for i in range(5):print("work2...")time.sleep(0.2)# 切换到第一个协程执行对应的任务g1.switchif __name__ == '__main__':# 创建协程指定对应的任务g1 = greenlet.greenlet(work1)g2 = greenlet.greenlet(work2)# 切换到第一个协程执行对应的任务g1.switch运行效果work1...work2...work1...work2...work1...work2...work1...work2...work1...work2... 6、gevent6.1 gevent的介绍greenlet已经实现了协程,但是这个还要人工切换,这里介绍一个比greenlet更强大而且能够自动切换任务的第三方库,那就是gevent 。
gevent内部封装的greenlet,其原理是当一个greenlet遇到IO(指的是input output 输入输出,比如网络、文件操作等)操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行 。
由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO
安装
pip3 install gevent 6.2 gevent的使用
import geventdef work(n):for i in range(n):print(gevent.getcurrent, i)g1 = gevent.spawn(work, 5)g2 = gevent.spawn(work, 5)g3 = gevent.spawn(work, 5)g1.joing2.joing3.join运行结果<Greenlet "Greenlet-0" at 0x26d8c970488: work(5)> 0<Greenlet "Greenlet-1" at 0x26d8c970598: work(5)> 0<Greenlet "Greenlet-2" at 0x26d8c9706a8: work(5)> 0<Greenlet "Greenlet-0" at 0x26d8c970488: work(5)> 1<Greenlet "Greenlet-1" at 0x26d8c970598: work(5)> 1<Greenlet "Greenlet-2" at 0x26d8c9706a8: work(5)> 1<Greenlet "Greenlet-0" at 0x26d8c970488: work(5)> 2<Greenlet "Greenlet-1" at 0x26d8c970598: work(5)> 2<Greenlet "Greenlet-2" at 0x26d8c9706a8: work(5)> 2<Greenlet "Greenlet-0" at 0x26d8c970488: work(5)> 3<Greenlet "Greenlet-1" at 0x26d8c970598: work(5)> 3<Greenlet "Greenlet-2" at 0x26d8c9706a8: work(5)> 3<Greenlet "Greenlet-0" at 0x26d8c970488: work(5)> 4<Greenlet "Greenlet-1" at 0x26d8c970598: work(5)> 4<Greenlet "Greenlet-2" at 0x26d8c9706a8: work(5)> 4可以看到,3个greenlet是依次运行而不是交替运行6.3 gevent切换执行
import geventdef work(n):for i in range(n):print(gevent.getcurrent, i)gevent.sleep(1)g1 = gevent.spawn(work, 5)g2 = gevent.spawn(work, 5)g3 = gevent.spawn(work, 5)g1.joing2.joing3.join运行结果<Greenlet at 0x7fa70ffa1c30: f(5)> 0<Greenlet at 0x7fa70ffa1870: f(5)> 0<Greenlet at 0x7fa70ffa1eb0: f(5)> 0<Greenlet at 0x7fa70ffa1c30: f(5)> 1<Greenlet at 0x7fa70ffa1870: f(5)> 1<Greenlet at 0x7fa70ffa1eb0: f(5)> 1<Greenlet at 0x7fa70ffa1c30: f(5)> 2<Greenlet at 0x7fa70ffa1870: f(5)> 2<Greenlet at 0x7fa70ffa1eb0: f(5)> 2<Greenlet at 0x7fa70ffa1c30: f(5)> 3<Greenlet at 0x7fa70ffa1870: f(5)> 3<Greenlet at 0x7fa70ffa1eb0: f(5)> 3<Greenlet at 0x7fa70ffa1c30: f(5)> 4<Greenlet at 0x7fa70ffa1870: f(5)> 4<Greenlet at 0x7fa70ffa1eb0: f(5)> 4 6.4 给程序打补丁
import geventimport timefrom gevent import monkeymonkey.patch_alldef work1(num):for i in range(num):print("work1....")time.sleep(0.2)def work2(num):for i in range(num):print("work2....")time.sleep(0.2)if __name__ == '__main__':g1 = gevent.spawn(work1, 3)g2 = gevent.spawn(work2, 3)g1.joing2.join
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Python绘制多维度专题地图
- 视频调整分辨率的python代码,一如既往地实用
- 一文带你搞定TCP滑动窗口
- 太好玩了!6种Python实现「实时」显示进度条
- 简单介绍Python中异常处理用法
- 详解一个Python库,用于构建精美数据可视化web app
- python的反射到底有什么用?
- 人生苦短,必须学会的写Python代码利器
- 慎用!Python 实现微信消息轰炸
- 交换机组网与PON组网哪个好?一文了解清楚
