muduo庫的學習6 Buffer的基本設計

2021-07-10 04:51:10 字數 2783 閱讀 7675

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類 該類主要負責...