1.使用應用層buffer的原因
這個陳碩對應的書裡面講地很清楚,見書p205 7.4.2
分為兩點
①為什麼需要output buffer
②為什麼需要input buffer
2.class buffer
class buffer : public muduo::copyable
;
3.具體分析
(1)資料成員
①buffer
採用vertor作為整個buffer的底層實現
好處是可以利用vector的一些特性進行一些方便的resize操作等等
②*** index
這個就是用來指示用的。
看完書中對應的7.4.4與7.4.5中的圖,很好理解。
(2)通用函式
①peek
取名類似於c檔案操作裡面的peek,那裡面是返回當前下標的位置。
這裡buffer::peek()返回的是記憶體中eadable段開始的位置。
因為readerindex是乙個相對位址(相對於buffer的首位址),所以peek就是通過簡單返回buffer.begin()+readerindex實現的。
②beginwrite
與peek相對,返回的是buffer.begin()+writerindex
(3)從緩衝區取出資料
①peekint
memcpy取走資料
②retrieve
移動下標
③readint
呼叫①peekint和②retrieve
(4)向緩衝區寫入資料
①haswriten
移動下標
先呼叫std::copy複製資料
再呼叫①haswriten
③readfd
為了解決7.4.3 p208提到的問題,並且從socket fd讀資料
(5)前向寫入
為了解決訊息長度開始位置問題,以很低的代價在前面新增幾個位元組
它自己就完成了a。移動小標 b。用std::copy向裡面寫內容
4.緩衝區大小設定問題
在p208頁提到了,我們既希望有乙個大的緩衝區(一次處理的資料更多,更少地記憶體分配與轉移),
又希望緩衝區足夠小(這樣即使乙個執行緒有許多併發連線也不會暫用太多記憶體)
muduo庫通過buffer::readfd函式試**決這個問題。
(1)基本思路
初始化時,每個connection的緩衝區為1k大小,
readfd中會有乙個棧記憶體的64k大小的extrabuf,
每次通過readv從connfd那邊讀取資料,先放入buffer之中,多出來的再放入extrabuf之中。
n = sockets::readv(connfd, vec, invcnt);
①ensurewritablebytes
首先驗證增加的長度vector buffer能不能裝下,如果不能就呼叫vector::resize到能
②std::copy
將資料複製到buffer中
③haswritten
改變writerindex
(3)buffer::readfd的好處
使用這個函式,①保證了大部分connection都只是有乙個很小的buffer空間
②但是每次讀取,有乙個extrabuf在那裡保證了幾乎每次只需要一次read就能將connfd上來的資料讀完。
而這個extrabuf相當於是該執行緒所有connection共用的,所以開銷很小
③每次如果buffer空間不夠幾乎是多處了多少,進行那麼多大小的擴容
且擴容後不再減少,以應對後面需要,減少記憶體分配次數。
(4)為什麼extrabuf是threadlocal
因為在每個thread中是乙個loop,loop裡面採用io multiplexing,這樣其實是每次最多有乙個connection在使用extrabuf,執行緒安全。
如果是多個執行緒使用乙個extrabuf,存在併發可能,執行緒不安全,需要加鎖。
但是這樣帶來了編碼難度的加大,帶來的提公升確並不是很多,所以不值得採用。還不如乙個thread乙個extrabuf。
(5)編碼細節
①iovcnt
位於buffer::readfd中,
const int iovcnt = (writable < sizeof extrabuf) ? 2 : 1;
這裡,iovcnt指示了readv用幾塊地方存放資料,
這句話保證了,一次讀取的最大大小為writable = 64k - 1 < extrabuf, iovcnt = 2, 這個時候一次可以讀取sizeof(writable + extrabuf) = 128k -1
(第6章)muduo網路庫
1 如果主動關閉連線,如何保證對方已經收到全部資料?2 如果應用層有緩衝區,如何保證先傳送完緩衝區的資料,然後再斷開連線?3 如果主動發起連線,但是對方主動拒絕,如何定期 帶back off地 重試?4 非阻塞網路程式設計該用邊沿觸發還是電平觸發?若是電平觸發,什麼時候關注epollout事件?會不...
muduo 日誌庫學習 二
logfile類和asynclogging類各有自己的buffer 在下文中,分別記為file buffer和async buffer 當使用者使用log 寫入日誌內容時,將會把日誌內容寫入到async buffer中,當async buffer寫滿了,就會把async buffer中的內容寫入到f...
muduo 日誌庫學習 一
大佬部落格 muduo的日誌庫由logstream logging logfile asynclogging組成。這裡主要說明一下,這些檔案 主要是檔案裡面對應的類 之間是怎麼關聯,並協同工作的。logstream類裡面有乙個buffer成員 乙個模板類,並非muduo buffer類 該類主要負責...