gevent实现简单的协程
协程,又称微线程。是指程序在执行线程A的时候如果碰到耗时操作,会自动切换到函数B执行,B碰到耗时操作自动切换回A。这一系列动作看起来像多线程,但是却只有一个线程执行。
优势:
- 占用资源更少
多任务占用资源排名 进程>线程>协程
- 执行效率极高,因为切换函数执行不是线程切换,而是程序本身控制,没有线程需要占用的资源。所以和线程对比,任务越多的时候,协程的优势越明显。
协程擅长处理IO密集型任务(耗时操作多),而不擅长处理计算密集型程序(耗时操作少)。
协程真正实现多任务核心:利用一个任务延时的时候切换另一个任务
使用gevent实现简单的协程
- import gevent 导入包
- 变量名 = gevent.spawn(函数名, 参数) 创建协程对象,碰到耗时操作自动执行
- 变量名.join() 等待协程运行结束
注:gevent是第三方库,需要执行下载安装
import gevent
def run():
"""执行函数"""
for i in range(5):
print("%d------%s" % (i, gevent.getcurrent()))
gevent.sleep(0.1) # 手动延时操作
def main():
g1 = gevent.spawn(run)
g2 = gevent.spawn(run)
g3 = gevent.spawn(run)
g1.join()
g2.join()
g3.join()
if __name__ == '__main__':
main()
执行结果:
0------<Greenlet "Greenlet-0" at 0x5011b58: run>
0------<Greenlet "Greenlet-1" at 0x51082d8: run>
0------<Greenlet "Greenlet-2" at 0x5108360: run>
1------<Greenlet "Greenlet-0" at 0x5011b58: run>
1------<Greenlet "Greenlet-1" at 0x51082d8: run>
1------<Greenlet "Greenlet-2" at 0x5108360: run>
2------<Greenlet "Greenlet-0" at 0x5011b58: run>
2------<Greenlet "Greenlet-1" at 0x51082d8: run>
2------<Greenlet "Greenlet-2" at 0x5108360: run>
3------<Greenlet "Greenlet-0" at 0x5011b58: run>
3------<Greenlet "Greenlet-1" at 0x51082d8: run>
3------<Greenlet "Greenlet-2" at 0x5108360: run>
4------<Greenlet "Greenlet-0" at 0x5011b58: run>
4------<Greenlet "Greenlet-1" at 0x51082d8: run>
4------<Greenlet "Greenlet-2" at 0x5108360: run>
jionall
gevent.joinall()方法会等待所有传入的greenlet协程运行结束后再退出,而不用每个对象都手动写join方法。
使用方法:
gevent.joinall([包含创建协程对象的列表])
代码:
import gevent
def run():
"""执行函数"""
for i in range(5):
print("%d------%s" % (i, gevent.getcurrent()))
gevent.sleep(0.1) # 手动延时操作
def main():
join_list = [gevent.spawn(run), gevent.spawn(run), gevent.spawn(run)]
gevent.joinall(join_list)
if __name__ == '__main__':
main()
运行结果:
0------<Greenlet "Greenlet-0" at 0x5821b58: run>
0------<Greenlet "Greenlet-1" at 0x59082d8: run>
0------<Greenlet "Greenlet-2" at 0x5908360: run>
1------<Greenlet "Greenlet-0" at 0x5821b58: run>
1------<Greenlet "Greenlet-1" at 0x59082d8: run>
1------<Greenlet "Greenlet-2" at 0x5908360: run>
2------<Greenlet "Greenlet-0" at 0x5821b58: run>
2------<Greenlet "Greenlet-1" at 0x59082d8: run>
2------<Greenlet "Greenlet-2" at 0x5908360: run>
3------<Greenlet "Greenlet-0" at 0x5821b58: run>
3------<Greenlet "Greenlet-1" at 0x59082d8: run>
3------<Greenlet "Greenlet-2" at 0x5908360: run>
4------<Greenlet "Greenlet-0" at 0x5821b58: run>
4------<Greenlet "Greenlet-1" at 0x59082d8: run>
4------<Greenlet "Greenlet-2" at 0x5908360: run>