在上一篇里面介绍了gevent的最主要的功能,先来来了解一下gevent里面一些更加高级的功能。
事件
事件是一种可以让greenlet进行异步通信的手段。
AsyncResult 是 event对象的扩展能够让你来发送值并且带有一定延迟。这种功能被成为feature或deferred,当它拿到一个未来的值的引用时,能够在任意安排好的时间内让它起作用。
队列
队列是一个有序的数据集合,通常有 put/get 的操作,这样能让队列在有在有greenletJ进行操作的时候能够进行安全的管理。
例如,如果greenlet从队列中取出了一项数据,那么这份数据就不能被另一个greenlet取出。
执行的结果如下:
队列的 put/get 操作在需要的情况下也可以阻塞程序的执行。
put 和 get 操作都有非阻塞的副本,就是 put_nowait 和 get_nowait。
在下面代码的例子里,运行一个叫boss的方法,同时运行worker方法,并且对队列有一个限制:队列的子项不能超过3个。这个限制意味着 put 操作在队列里面有足够空间之前会阻塞。相反,如果队列里没有任何子项,get操作会阻塞,同时也需要超时的机制,当一个操作在阻塞超过一定时间后会抛出异常。
代码的执行结果如下:
组和池
组是一个由greenlet组成的集合,并且能够被统一管理。
这在管理一组异步任务的时候会很有用。
Group还提供了一个API来分配成组的greenlet任务,并且通过不同的方法来获取结果。
执行结果如下:
池是用来处理当拥有动态数量的greenlet需要进行并发管理(限制并发数)时使用的。
这在处理大量的网络和IO操作的时候是非常需要的。
经常在创建gevent驱动程序的时候,整个服务需要围绕一个池的结构来执行。
锁和信号量
信号量是低级别的同步机制,能够让greenlet在执行的时候互相协调并且限制其并发数。信号量暴露了两个方法,acquire 和 release。如果信号量范围变成0,那么它会阻塞住直到另一个greenlet释放它的获得物。
一下是代码的执行结果:
如果把信号量的数量限制为1那么它就成为了锁。它经常会在多个greenlet访问相同资源的时候用到。
本地线程
Gevent还能够让你给gevent上下文来指定那些数据是本地的。
以下是执行结果:
很多集成了gevent的框架把HTTP的session对象存在gevent 本地线程里面。比如下面的例子:
子进程
在gevent 1.0版本中,gevent.subprocess 这个库被添加上。这个库能够让子进程相互协调地执行。
执行结果: