nginx sendfile 引數解釋

2021-07-09 15:25:24 字數 1471 閱讀 5255

sendfile

現在流行的web 伺服器裡面都提供 sendfile 選項用來提高伺服器效能,那到底 sendfile是什麼,怎麼影響效能的呢?sendfile實際上是 linux2.0+以後的推出的乙個系統呼叫,web伺服器可以通過調整自身的配置來決定是否利用 sendfile這個系統呼叫。先來看一下不用 sendfile的傳統網路傳輸過程:

read(file,tmp_buf, len);

write(socket,tmp_buf, len);

硬碟 >> kernel buffer >> user buffer>> kernel socket buffer >>協議棧

一般來說乙個網路應用是通過讀硬碟資料,然後寫資料到socket 來完成網路傳輸的。上面2行用**解釋了這一點,不過上面2行簡單的**掩蓋了底層的很多操作。來看看底層是怎麼執行上面2行**的:

1、系統呼叫 read()產生乙個上下文切換:從 user mode 切換到 kernel mode,然後 dma 執行拷貝,把檔案資料從硬碟讀到乙個 kernel buffer 裡。

2、資料從 kernel buffer拷貝到 user buffer,然後系統呼叫 read() 返回,這時又產生乙個上下文切換:從kernel mode 切換到 user mode。

3、 系統呼叫write()產生乙個上下文切換:從 user mode切換到 kernel mode,然後把步驟2讀到 user buffer的資料拷貝到 kernel buffer(資料第2次拷貝到 kernel buffer),不過這次是個不同的 kernel buffer,這個 buffer和 socket相關聯。

4、系統呼叫 write()返回,產生乙個上下文切換:從 kernel mode 切換到 user mode(第4次切換了),然後 dma 從 kernel buffer拷貝資料到協議棧(第4次拷貝了)。

上面4個步驟有4次上下文切換,有4次拷貝,我們發現如果能減少切換次數和拷貝次數將會有效提公升效能。在kernel2.0+ 版本中,系統呼叫 sendfile() 就是用來簡化上面步驟提公升效能的。sendfile() 不但能減少切換次數而且還能減少拷貝次數。

再來看一下用 sendfile()來進行網路傳輸的過程:

sendfile(socket,file, len);

硬碟 >> kernel buffer (快速拷貝到kernelsocket buffer) >>協議棧

1、 系統呼叫sendfile()通過 dma把硬碟資料拷貝到 kernel buffer,然後資料被 kernel直接拷貝到另外乙個與 socket相關的 kernel buffer。這裡沒有 user mode和 kernel mode之間的切換,在 kernel中直接完成了從乙個 buffer到另乙個 buffer的拷貝。

2、dma 把資料從 kernelbuffer 直接拷貝給協議棧,沒有切換,也不需要資料從 user mode 拷貝到 kernel mode,因為資料就在 kernel 裡。

文章參考:

Nginx sendfile原理詳解

配置語法 語法 sendfile on off 預設值 sendfile off 上下文 http,server,location,if in location 說明 sendfile值為on,指定使用sendfile系統呼叫來傳輸檔案。sendfile系統呼叫在兩個檔案描述符之間直接傳遞資料 完全...

預設引數,命名引數,可變引數

def sayname name string pk unit sayname 其中預設引數為pk,所以此時輸出pk sayname dog 此時傳入引數dog,那麼就以你當前傳入的引數為準,輸出dogdef speed distance float time float float println...

C 方法引數 值引數,引用引數,輸出引數

使用值引數,通過複製實參的值到形參的方式,把資料傳遞到方法,方法被呼叫的時候,系統做如下操作 在棧中為形參分配空間 複製實參到形參。注意 乙個值引數的實參不一定是變數,它可以是任何能夠計算成相應資料型別的表示式。在把變數用作實參之前,變數必須被賦值 除非是輸出引數,這個稍後介紹 對於引用型別,變數可...