原創,請註明出處:http://www.cnblogs.com/stonehat/p/6286235.html
Libevent 是一個事件驅動框架, 不能僅說他是一個網絡庫。
notejs就是採用與libevent相似的libev來作核心驅動的。
Libevent支持三種事件:io事件、信號事件、時間事件,而且事件的設置和使用方式是同樣的。
libevent的核心原理是採用io多路複用的方式來單線程處理事件。至於爲何這麼說,下面會分別對三種事件進行解釋。
io事件: io事件包含socket可讀、可寫、斷開、設備可讀、可寫等和IO相關的事件, libevent主要採用了epoll模型來進行i/o事件的多路複用(我說的是linux上,libevent也封裝了select,poll模型,下面僅說採用epoll的狀況)。 一句話解釋epoll模型:就是在內核管理的設備或者資源上設置等待隊列,當資源出現的時候,系統會通知epoll_wait喚醒,進行事件的處理。 總的來講, i/o事件的事件驅動依賴於操做系統。
時間事件: 時間事件,能夠簡單的解釋一下, 若是咱們想在500ms後執行一段代碼,那麼,就能夠在libevent上面設置一個時間事件,代碼封裝到回調函數裏面去。 若是看過epoll或者select的使用方式,你就會知道epoll_wait能夠設置一個timeout,等待timeout這個時長,若是沒有事件發生,也會返回。時間事件的處理就 將全部時間事件要等待時間最少的設置爲timeout時間,這樣,即便什麼i/o事件也沒有發生,也能在timeout後,處理該處理的時間事件。
信號事件: 簡單的解釋一下, 即便和i/o無關的信號,也能夠做爲一個事件進行處理,信號在linux中是進程間通訊方式之一, A能夠發出一個信號, B能夠接受信號,B接受以後能夠進行一些操做,問題是, libevent想把信號事件也統一一塊兒處理, 其原理是, 將信號事件這種和I/O無關的事件轉換爲和I/O有關的,充分利用現有模型統一處理。事實上, 信號事件是採用一個client socket 和一個server socket, client socket只能寫, server socket只能讀, server sockert將recv到的client socket的文件描述符放到了epoll的事件集合中, 永遠不刪。 當收到系統信號的時候, 經過client socket進行發送, server socket收到數據,就會觸發epoll_wait喚醒,若是發現這是server socket的事件,就會對信號事件進行遍歷找到那個等待的。
ps:我的以爲libevent應該添加字符串信號啥的自定義信號, 好擴展
事件的結構:
時間事件:採用最小堆組織, 時間最少的在頂部, 插入和刪除都是log(N),主要是方便找到最小等待時間,方便設置time_out時間。
I/O事件:雙向鏈表。
信號事件: 雙向鏈表
激活事件:是libevent 的epoll_wait喚醒後,獲得的全部要處理的事件雙向鏈表。
主循環:
libevent採用一個主循環來處理全部事件處理和事件等待。