关于gevent的协程间通信及队列和事件event用法

简介:

前言:

    今天就写点gevent的高级点的用法,对于我来说 这些也是常用的gevent模块。


gevent的AsyncResutl模块的用途,看字眼的意思是一个异步的任务的结果。 其实官方的说法也让人有些发蒙。  其实说白了就是协程间的通信,我是老板,让大哥和小弟同事去收账,小弟做完了后,会等大哥来问话。 如果小弟没有完成,还在做着事情,那大哥会在一个时间里,等待小弟返回结果。一直等 !


在实战中这个就很有意思了。   我们同时做一个事情,但是我们又需要互相的帮助,或者是互相的通信。  这个时候就可以用asyncresult。 


wKiom1PnhUWzgzDyAALebVnD0sk717.jpg


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#coding:utf-8
#http://rfyiamcool.blog.51cto.com/1030776/1538367
import  gevent
from  gevent.event  import  AsyncResult
 
=  AsyncResult()
 
def  xiaodi():
     """
     一会堵上10秒 !
     """
     print  "xiaodi 开始"
     gevent.sleep( 10 )
     a. set ( 'hello world' )
     print  "xiaodi 结束"
 
def  dage():
     """
     需要等待xiaodi完事了后,他才能i live
     """
     print  'dage 这里是先开始的...'
     print  a.get()  # blocking
     print  'I live!'
 
gevent.joinall([
     gevent.spawn(xiaodi),
     gevent.spawn(dage),
])


wKiom1PnhcfCgQR1AACraArCixU937.jpg


这里是gevent的事件用法。rawlink是注册一个回调,wait是等待任务的完成之后,才能后续进行。    他的用法有些像twisted的一些思想,注册事件,事件和回调函数关联。    gevent最大的优势是用同步的写法,实现异步的功能。 所以这功能不太实用。 

e = Event()

e.rawlink(callback_def)

e.wait()

e.xxx


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#coding:utf-8
#http://rfyiamcool.blog.51cto.com/1030776/1538367
import  gevent
import  time
 
def  event_setter(e):
     print  '开始搞了...'
     e.rawlink(event_callback)
     gevent.sleep( 2 )
     print  '222...'
     e. set ()
 
def  event_waiter(e):
     print  '等待...'
     e.wait()
     print  '等待 end'
 
def  event_callback(e):
     print  "回调..."
 
def  try_event():
     from  gevent.event  import  Event
     =  Event()
     gevent.joinall([
         gevent.spawn(event_setter, e),
         gevent.spawn(event_waiter, e),
         gevent.spawn(event_waiter, e),
         gevent.spawn(event_waiter, e),
         gevent.spawn(event_waiter, e),
         gevent.spawn(event_waiter, e),
         gevent.spawn(event_waiter, e),
     ])
 
try_event()


wKioL1Pnh1_BrCEqAADmho95wNE429.jpg


gevent自己有个gevent.queue,我自己没做测试,倒是看一些老外再谈论,在数据大的数据的时候,要比pyhton queue本身的队列要抗用。


gevent queue 的队列功能很是丰富 ! 

1
2
3
4
5
6
7
8
>>> queue  =  gevent.queue.Queue()
>>> queue.put( 1 )
>>> queue.put( 2 )
>>> queue.put(StopIteration)
>>>  for  item  in  queue:
...     print  item
1
2

原文: http://rfyiamcool.blog.51cto.com/1030776/1538367


下面是一个比较完整的例子,大家跑跑:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import  gevent  from  gevent.queue  import  Queue
 
tasks  =  Queue() def  worker(n):
     while  not  tasks.empty():
         task  =  tasks.get()         print ( 'Worker %s got task %s'  %  (n, task))
         gevent.sleep( 0 )     print ( 'Quitting time!' ) def  boss():
     for  in  xrange ( 1 , 25 ):
         tasks.put_nowait(i)
 
gevent.spawn(boss).join()
 
gevent.joinall([
     gevent.spawn(worker,  'fuck shencan' ),
     gevent.spawn(worker,  'fuck zb' ),
     gevent.spawn(worker,  'fuck liudehua' ),
])


wKiom1PnhtzwO_JeAAKZRTYXFXo430.jpg


gevent队列的方法还是很牛叉的。 比如put 推送队列,get取出队列,里面可以加几个选项 堵塞和超时时间。


1
2
3
4
5
6
7
8
9
put(item, block = True , timeout = None ) 往队列放入数据,可选是否阻塞和超时时间
put_nowait(item) 非阻塞的往队列放入数据,队列已满时抛出Full Exception
get(block = True , timeout = None ) 从队列读出数据,可选是否阻塞和超时时间
get_nowait() 费阻塞地从队列读出数据,队列为空是抛出Empty Exception
peek(block = True , timeout = None ) 和get()类似,但获取的数据不会从队列移除
peek_nowait() 类似get_nowait()
empty() 队列为空返回 True
full() 队列已满返回 True
qsize() 返回队列长度,即队列中的数据数,而非Queue(maxlength)初始化时的maxlength


原文:http://rfyiamcool.blog.51cto.com/1030776/1538367 


外加一个gevent执行状态的判断。

1
2
3
4
5
started  表明是否gevent已经开始
ready()  表明是否gevent已经停止
successful()  表明是否gevent已经停止并且没有抛出异常
value  - -   任意,gevent返回的值
exception  - -   gevent异常,gevent内部实例没有被捕抓的异常


wKioL1PnjTOgO7K3AAOYOijH5_w822.jpg







 本文转自 rfyiamcool 51CTO博客,原文链接:http://blog.51cto.com/rfyiamcool/1538367,如需转载请自行联系原作者

相关文章
|
网络协议 调度 开发者
python中gevent基于协程的并发编程模型详细介绍
`gevent`是Python的第三方库,提供基于协程的并发模型,适用于I/O密集型任务的高效异步编程。其核心是协程调度器,在单线程中轮流执行多个协程,通过非阻塞I/O实现高并发。主要特点包括协程调度、事件循环的I/O模型、同步/异步编程支持及易用性。示例代码展示了一个使用`gevent`实现的异步TCP服务器,当客户端连接时,服务器以协程方式处理请求,实现非阻塞通信。
228 0
|
3月前
|
Go 调度 Python
Golang协程和Python协程用法上的那些“不一样”
本文对比了 Python 和 Go 语言中协程的区别,重点分析了调度机制和执行方式的不同。Go 的协程(goroutine)由运行时自动调度,启动后立即执行;而 Python 协程需通过 await 显式调度,依赖事件循环。文中通过代码示例展示了两种协程的实际运行效果。
191 7
|
存储 运维 API
源码解密协程队列和线程队列的实现原理(一)
源码解密协程队列和线程队列的实现原理(一)
257 1
|
存储 安全 API
源码解密协程队列和线程队列的实现原理(二)
源码解密协程队列和线程队列的实现原理(二)
132 1
|
存储 Python
python使用gevent库来创建协程,并通过协程实现并发执行不同的任务
```markdown 这段Python代码利用`gevent`库实现并发执行协程。定义了两个打印函数`f1`和`f2`,分别输出"csdn"和"yyds"。代码首先创建列表`t_l`,并启动5个`f1`协程,将其加入列表并等待所有协程完成。随后,同样方式启动5个`f2`协程,存入`t1_l`列表并等待执行完毕。整体展示了`gevent`的协程并发操作。 ```
144 1
|
Python
164 python网络编程 - 协程(gevent版)
164 python网络编程 - 协程(gevent版)
144 0
|
API Python
Gevent----非官方的python协程库
Gevent----非官方的python协程库
182 0
|
Go 调度 Python
大道如青天,协程来通信,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang通道channel的使用EP14
众所周知,Go lang的作用域相对严格,数据之间的通信往往要依靠参数的传递,但如果想在多个协程任务中间做数据通信,就需要通道(channel)的参与,我们可以把数据封装成一个对象,然后把这个对象的指针传入某个通道变量中,另外一个协程从这个通道中读出变量的指针,并处理其指向的内存对象。
大道如青天,协程来通信,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang通道channel的使用EP14
|
缓存 Go
学习golang(11) 初探:协程(2) 协程间通信
学习golang(11) 初探:协程(2) 协程间通信
334 0
|
网络协议 安全 Python
【Tornado】协程队列和异步DNS解析器在Tornado项目里的实战表现已经运用详解
【Tornado】协程队列和异步DNS解析器在Tornado项目里的实战表现已经运用详解
278 2