日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

libevent源码学习-----阅读心得

發(fā)布時(shí)間:2024/4/19 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 libevent源码学习-----阅读心得 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

框架設(shè)計(jì)思路

  • libevent使用統(tǒng)一事件源將所有問(wèn)題都轉(zhuǎn)化為event,比如將套接字/信號(hào)/描述符都在內(nèi)部轉(zhuǎn)化為event,由相應(yīng)的io多路復(fù)用函數(shù)進(jìn)行監(jiān)控。
  • 為了提供對(duì)超時(shí)event的支持,libevent將所有的超時(shí)時(shí)間都轉(zhuǎn)化為絕對(duì)時(shí)間,這就將雜亂無(wú)章的超時(shí)event有序管理起來(lái),同時(shí)采用最小堆存儲(chǔ)那些具有超時(shí)時(shí)間的event,這樣當(dāng)堆頂event沒有超時(shí),那么堆中所有event都不會(huì)超時(shí)。
  • libevent采用Reactor反應(yīng)器模式來(lái)處理所有的event,內(nèi)部使用io多路復(fù)用進(jìn)行監(jiān)控,又因?yàn)樾枰蒷ibevent主動(dòng)調(diào)用用戶的回調(diào)函數(shù),所以libevent內(nèi)部大量使用函數(shù)指針保存和調(diào)用用戶提供的回調(diào)函數(shù),其實(shí)就是利用函數(shù)指針實(shí)現(xiàn)多態(tài)
  • 是出現(xiàn)一個(gè)激活event就調(diào)用對(duì)應(yīng)回調(diào)函數(shù),還是先將所有激活event存在一起,統(tǒng)一調(diào)用。顯然更好的是后者,因?yàn)榭梢詫?duì)激活event進(jìn)行管理,包括event優(yōu)先級(jí)等
  • 至此就可以在event_base_new,event_new,event_add基礎(chǔ)上進(jìn)行擴(kuò)展,包括封裝socket api,設(shè)計(jì)tcp緩沖區(qū)等

源碼閱讀心得
其實(shí)主要還是細(xì)節(jié)問(wèn)題,拋開各種錯(cuò)誤處理不管,libevent可以學(xué)習(xí)的內(nèi)容非常多

對(duì)io多路復(fù)用函數(shù)的封裝,實(shí)現(xiàn)跨平臺(tái)
如何對(duì)各種io復(fù)用函數(shù)的接口實(shí)現(xiàn)統(tǒng)一,是對(duì)其封裝首先要考慮的問(wèn)題。為了統(tǒng)一,就需要設(shè)計(jì)一個(gè)統(tǒng)一的接口,在對(duì)io復(fù)用進(jìn)行封裝時(shí)都根據(jù)這個(gè)統(tǒng)一接口進(jìn)行。
libevent便是設(shè)計(jì)了統(tǒng)一的接口struct,內(nèi)部包含io復(fù)用名字字符串,io函數(shù)的各種接口的函數(shù)指針。這樣在封裝時(shí)只需要每一個(gè)io復(fù)用函數(shù)都按照這種格式提供響應(yīng)的字符串和函數(shù)指針,在base的調(diào)用中就不需要關(guān)系具體是哪個(gè)io函數(shù)了
此外對(duì)于每一個(gè)io復(fù)用函數(shù)使用的數(shù)據(jù),比說(shuō)說(shuō)poll的pollfd,epoll的epoll_event,select的fd_set也需要統(tǒng)一的管理,但這個(gè)管理就不需要那么中規(guī)中矩了,因?yàn)檫@些數(shù)據(jù)是在每個(gè)io多路復(fù)用函數(shù)內(nèi)部接口使用的,而這些內(nèi)部接口如何使用數(shù)據(jù)在寫程序的時(shí)候就是知道的,比如說(shuō)epoll知道如何使用epoll_event,select知道如何使用fd_set等。所以在設(shè)計(jì)時(shí)為了方便簡(jiǎn)單的封裝以下就可以。
比較特別的是select對(duì)于fd_set的封裝,因?yàn)槊看蝧elect之前都需要手動(dòng)FD_ZERO,然后手動(dòng)FD_SET所有fd,很麻煩,所以在對(duì)其封裝時(shí)對(duì)每個(gè)fd_set都有一份拷貝,添加刪除fd時(shí)用一個(gè),select時(shí)將這個(gè)fd_set拷貝到另一個(gè),使用拷貝后的調(diào)用select
對(duì)于跨平臺(tái),其實(shí)就是把所有平臺(tái)能夠使用的io函數(shù)都羅列出來(lái),根據(jù)預(yù)編譯頭進(jìn)行篩選
可以參考io多路復(fù)用的封裝和使用


將信號(hào)統(tǒng)一到event上
信號(hào)發(fā)生和描述符可讀可寫沒有半點(diǎn)關(guān)系,想要把它們扯上關(guān)系,libevent的做法還是很值得學(xué)習(xí)的
具體可以參考統(tǒng)一事件源


數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)
libevent內(nèi)部實(shí)現(xiàn)了hashmap,max-heap,queue,這些可以參考STL的源碼實(shí)現(xiàn)


tcp緩沖區(qū)的設(shè)計(jì)
內(nèi)核提供的tcp緩沖區(qū)某種程度上已經(jīng)可以滿足需求了,但是當(dāng)寫入一個(gè)已經(jīng)滿的內(nèi)核tcp緩沖區(qū)時(shí),io函數(shù)會(huì)出現(xiàn)阻塞,如果非阻塞io則會(huì)出現(xiàn)錯(cuò)誤,極大增加了不穩(wěn)定性。
其實(shí)設(shè)計(jì)緩沖區(qū)的目的就在于把所有的io函數(shù)的讀寫的數(shù)據(jù)都經(jīng)由自己設(shè)計(jì)的緩沖區(qū)轉(zhuǎn)發(fā)。比如說(shuō),使用send寫入數(shù)據(jù),會(huì)直接寫到程序緩沖區(qū),待tcp內(nèi)核緩沖區(qū)處于可寫,由程序自動(dòng)寫入。而用戶不會(huì)知道在這個(gè)過(guò)程中其實(shí)經(jīng)過(guò)了一個(gè)程序緩沖區(qū)
需要學(xué)習(xí)的就是緩沖區(qū)如何增加刪除以及數(shù)據(jù)如何讀出和寫入,對(duì)于緩沖區(qū)的動(dòng)態(tài)變化,libevent做的還是很好的。一個(gè)鏈表連接著一個(gè)個(gè)內(nèi)存塊,每次寫入數(shù)據(jù)都找最后一個(gè)有數(shù)據(jù)的內(nèi)存塊后面的內(nèi)存塊,讀數(shù)據(jù)尋找第一個(gè)有數(shù)據(jù)的內(nèi)存塊,然后對(duì)內(nèi)存塊進(jìn)行調(diào)整

總結(jié)

以上是生活随笔為你收集整理的libevent源码学习-----阅读心得的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。