python的libev庫pyev一點心得

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_interval
print loop.timeout_interval
while 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就可以實現我們要的場景了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章