libev的使用——结合Socket编程
首先推薦幾個我認為學習libev比較好的blog,最后一個地址是官方文檔,給了我很多幫助:
http://vimersu.win/blog/2014/03/06/libev-study/
http://www.cnblogs.com/dirlt/archive/2011/09/07/2169344.html#sec-1
http://blog.csdn.net/woxiaozhi/article/details/16963641
http://www.cnblogs.com/wunaozai/p/3950249.html
http://wenku.baidu.com/link?url=z021OoHoevOJDNP1IVTmEcWvTKRoNKlfzi96k8gUKvcnvdZxlvW4diCihYlxFYRJVjtHSVtYrN451MIqlyznsmO0wUvjRslNPGOZopSIhP_
一.libev原理
之前簡單寫過一篇libev的學習:http://blog.csdn.net/cxy450019566/article/details/52416349
有時間可以看看,沒時間直接看這一篇文章。
需要理解的第一句話:Libev的核心是一個event loop。一個event loop,通俗講就是一個不停在循環運行的事件。
需要理解的第二句話:Libev通過分配和注冊watcher對不同類型的事件進行監聽,當監聽被觸發時,進行相應的操作。在一個event loop中,我們可以設定對很多libev支持的事件(見上一篇博客)的監聽watcher,這些事件的監聽是異步進行的,觸發任意一個監聽的事件,都可以根據我們的設定進行某些操作。
理解了這兩句話,你就可以理解libev的作用,以及怎樣來使用libev。
二.通過簡單示例了解libev基本用法
我們從官方示例,來學習libev的基本用法。
[cpp] view plain copy
通過上面的例子,就可以知道libev使用的思路:
首先,定義一個eventloop大容器 struct ev_loop,和想要的監控事件ev_XXX。
其次,初始化想要監控的事件,設置好回調函數和相應的參數ev_XXX_init 。
接下來,讓想要監控的事件都投身到大容器中ev_XXX_start。
最后,讓大容器帶著小容器一起運行起來 ev_run 。
?
三.常用函數詳解
1.event loop 相關
(1)從創建說起:
我們默認使用EV_DEFAULT類型的loop,使用一下語句來創建:struct ev_loop *loop = EV_DEFAULT;
EV_DEFAULT宏是以下指令:
ev_default_loop(EVBACKEND_POLL | EVBACKEND_SELECT | EVFLAG_NOENV);
返回一個最基礎的ev_loop,并自動完成它的初始化,注意,如果程序中已經執行過該創建,將直接返回之前的創建。除此之外,更多自定義loop,可以使用該函數:struct ev_loop*ev_loop_new (unsigned int flags)。
(2)讓ev_loop運行起來
使用函數ev_run(loop, int flags)。
這里解釋一下flags的作用,用于設置ev_loop的運行方式:
通常設置為0,表示該ev_loop在所有watcher結束后停止,也可以手動break,官方鼓勵手動break。
除了0之外,還有一些選擇,如EVRUN_NOWAIT、EVRUN_ONCE。具體請看官方文檔。
ev_run函數的源碼說明。推薦博文:http://www.cnblogs.com/xiangshancuizhu/archive/2013/08/10/3250558.html
(3)ev_loop的停止
前面已經說過,在flags設置為0的情況下,停止主要靠全部watcher停止或者手動break。
手動break用以下函數:ev_break (loop,how)
其中,how代表停止的方式:
EVBREAK_ONE:停止最久遠的那個ev_run
EVBREAK_ALL:停止所有的ev_run
2.ev_TYPE公共基礎
(1)watcher對應的幾種狀態
initialiased:調用init函數初始化
active:調用start進行注冊
pending:已經觸發事件但是沒有處理
inactive:調用stop注銷。這個狀態等同于initialised這個狀態。
(2)ev_TYPE對應不同類型的時間監控,共有的標準化函數主要如下:
[cpp] view plain copy3.ev_io相關
(1)ev_io結構
ev_io用來監聽io事件,當有標準輸入或輸出時,則會觸發事件,執行回調函數。
[cpp] view plain copy(2)初始化
兩種方式:
方式一:ev_init(ev_TYPE *watcher, callback) ,ev_io_set(ev_io *ev, intfd, int events)
方式二:ev_io_init(ev_io*ev, callback,int fd, int events)
即需要設置監聽watcher,回調函數callback,文件描述符fd,監聽的事件events。
(3)運行和停止
ev_io_start(EV_P_ev_io * w):綁定到ev_loop上
ev_io_stop(EV_P_ev_io * w):從ev_loop上撤離
4.ev_timer相關
(1)ev_timer結構
ev_timer是一個相對時間的定時器,會在給定的時間點觸發事件,還可以在固定的時間間隔之后再次觸發超時事件。
[cpp] view plain copy(2)初始化
同樣兩種方式:
方式一:ev_init(ev_TYPE *watcher, callback) ,ev_timer_set (ev_timer *,ev_tstamp after, ev_tstamp repeat)
方式二:ev_timer_init(ev_timer *, callback, ev_tstamp after, ev_tstamp repeat)
即需要設置監聽watcher,回調函數callback,定時器時間after,是否重復repeat。
其中,repeat設置為0表示定時器只觸發一次,設置為正整數則間隔after秒一直不斷觸發。
(3)運行和停止
ev_timer_start(EV_P_ev_io * w):綁定到ev_loop上
ev_timer_stop(EV_P_ev_io * w):從ev_loop上撤離
(4)其它函數
ev_timer_again(loop, ev_timer *) :重啟,對于不同狀態的timer效果不同。
ev_tstampev_timer_remaining (loop, ev_timer *):返回現在到下一次觸發定時器之間的時間。
四.在Socket編程的應用實例
libev用在Socket編程上有幾個好處,用ev_timer可以控制發送頻率,用ev_io可以方便地異步進行包的接收。下面的實例就實現的這個流程,直接用代碼解釋了:
[cpp] view plain copy
總結
以上是生活随笔為你收集整理的libev的使用——结合Socket编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: boost bind使用指南
- 下一篇: mmap使用实例