Gevent官网文档地址:http://www./contents.html 基本概念我们通常所说的协程Coroutine其实是corporate routine的缩写,直接翻译为协同的例程,一般我们都简称为协程。 在linux系统中,线程就是轻量级的进程,而我们通常也把协程称为轻量级的线程即微线程。 进程和协程下面对比一下进程和协程的相同点和不同点: 相同点: shell进程和hello进程:
当我们挂起一个执行流的时,我们要保存的东西:
而寄存器和栈的结合就可以理解为上下文,上下文切换的理解: 操作系统保持跟踪进程运行所需的所有状态信息。这种状态,就是上下文。 不同点:
线程和协程既然我们上面也说了,协程也被称为微线程,下面对比一下协程和线程:
我们通过下面的图更容易理解: 从上图可以看出,协程只是在单一的线程里不同的协程之间切换,其实和线程很像,线程是在一个进程下,不同的线程之间做切换,这也可能是协程称为微线程的原因吧 继续分析协程: GeventGevent是一种基于协程的Python网络库,它用到Greenlet提供的,封装了libevent事件循环的高层同步API。它让开发者在不改变编程习惯的同时,用同步的方式写异步I/O的代码。 使用Gevent的性能确实要比用传统的线程高,甚至高很多。但这里不得不说它的一个坑:
既然Gevent用的是Greenlet,我们通过下图来理解greenlet: 每个协程都有一个parent,最顶层的协程就是man thread或者是当前的线程,每个协程遇到IO的时候就把控制权交给最顶层的协程,它会看那个协程的IO event已经完成,就将控制权给它。 下面是greenlet一个例子 1 from greenlet import greenlet 2 3 def test1(x,y): 4 z = gr2.switch(x+y) 5 print(z) 6 7 8 def test2(u): 9 print(u) 10 gr1.switch(42) 11 12 13 gr1 = greenlet(test1) 14 gr2 = greenlet(test2) 15 16 17 gr1.switch("hello",'world') greenlet(run=None, parent=None): 创建一个greenlet实例. 下面是gevent的一个例子: 1 import gevent 2 3 def func1(): 4 print("start func1") 5 gevent.sleep(1) 6 print("end func1") 7 8 9 def func2(): 10 print("start func2") 11 gevent.sleep(1) 12 print("end func2") 13 14 gevent.joinall( 15 [ 16 gevent.spawn(func1), 17 gevent.spawn(func2) 18 ] 19 ) 关于gevent中队列的使用gevent中也有自己的队列,但是有一个场景我用的过程中发现一个问题,就是如果我在协程中通过这个q来传递数据,如果对了是空的时候,从队列获取数据的那个协程就会被切换到另外一个协程中,这个协程用于往队列里put放入数据,问题就出在,gevent不认为这个放入数据为IO操作,并不会切换到上一个协程中,会把这个协程的任务完成后在切换到另外一个协程。我原本想要实现的效果是往对了放入数据后就会切换到get的那个协程。(或许我这里理解有问题)下面是测试代码: 1 import gevent 2 from gevent.queue import Queue 3 4 5 def func(): 6 for i in range(10): 7 8 print("int the func") 9 q.put("test") 10 11 def func2(): 12 for i in range(10): 13 print("int the func2") 14 res = q.get() 15 print("--->",res) 16 17 q = Queue() 18 gevent.joinall( 19 [ 20 gevent.spawn(func2), 21 gevent.spawn(func), 22 ] 23 ) 这段代码的运行效果为: 如果我在fun函数的q.put("test")后面添加gevent.sleep(0),就会是如下效果: 原本我预测的在不修改代码的情况下就应该是第二个图的结果,但是实际却是第一个图的结果(这个问题可能是我自己没研究明白,后面继续研究) 关于Gevent的问题就像我上面说的gevent和第三方库配合使用会有一些问题,可以总结为: 不过总的来说gevent目前为止还是有很多缺陷,并且不是官网标准库,而在python3中有一个官网正在做并且在3.6中已经稳定的库asyncio,这也是一个非常具有野心的库,非常建议学习,我也准备后面深入了解 |
|