python的libev库pyev一点心得

来源:互联网 发布:售楼软件哪家好 编辑:程序博客网 时间:2024/06/05 14:29

http://pythonhosted.org/pyev/examples.html
这是官方文档给的例子,基本需求对照着看了就可以写了,一般用事件模型,无非就是关心一个有连接可以accept,一个有数据可以read的事件,然后就是定时器,这里都有了。
1.例子中的reset函数
事件每次触发结束了,都要调用reset函数,reset函数的作用是重新注册一次事件,为什么要这么做了?以前用惯了libevent的EV_PERSIST事件,不需要你重新再激活一次事件。但是我看了python的libev源码,里面只支持两个事件EV_READ和EV_WRITE,所以pyev的做法只能每次事件触发回调结果了都要调用reset重新激活。
2.关于loop循环
一般做法:
loop = pyev.default_loop()
loop.start()

这种做法有一个弊端,比如如果外部还想做一些自己的事情,和事件循环无关的,用epoll就会灵活多了,以下伪代码表示一下

while(true){    epoll_wait(1)    function()}

这里表示了一下大概意思,每次epoll_wait循环出来,我外面都可以执行一下自己的事情,超时时间设置为1s,也就是1s内都没有事件触发,那就跳出来,执行一下我的function,再进去wait。这是很多场景需要的功能。于是我找了pyev的这个超时功能。这里是个坑,别看官方文档上说有timeout_interval选项,我尝试改了这个值

loop = pyev.Loop(flags=pyev.EVFLAG_AUTO, callback=None, data=None, io_interval=3.0, timeout_interval=3.0, debug=False)print loop.io_intervalprint loop.timeout_intervalwhile True:    loop.start(pyev.EVRUN_ONCE)

打印出来确实修改了,但是!进入循环之后它根本就不会出来!一开始我还以为是我用错了,试了好多遍,最后又只好去看pyev的源码,才发现了坑。
这里写图片描述
函数入口就定义了double io_interval = 0.0, timeout_interval = 0.0;
创建一个loop的时候,根本没有管你给的值是多少,进入创建的函数里面,它就自己给了0.0直接写死了,这个所谓的超时毫无作用!
现在针对上述代码,要怎么实现我们要的场景?我们可以创建一个定时器事件,注册到loop,然后你想要的超时时间给这个定时器的定时时间,定时器每次触发了,loop.start就会跳出来了,然后接下来执行你的function,这就是用最小定时器事件去触发跳出循环的一个方法。这个是参考的C的libev的做法
这里写图片描述
从ev_once的入参可以看到timeout是超时时间,最后是给到ev_timer了,用最小定时器来触发一次回调退出,这样再在ev_once外面套上while就可以实现我们要的场景了。

原创粉丝点击