1. 程式人生 > >Linux Sendfile的優勢

Linux Sendfile的優勢

Sendfile函式在兩個檔案描寫敘述符之間直接傳遞資料(全然在核心中操作,傳送),從而避免了核心緩衝區資料和使用者緩衝區資料之間的拷貝,操作效率非常高,被稱之為零拷貝。

Sendfile函式的定義例如以下:

#include <sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

1.傳統方式read/write send/recv

在傳統的檔案傳輸裡面(read/write方式),在實現上事實上是比較複雜的,需要經過多次上下文的切換。我們看一下例如以下兩行程式碼:

1.read(file, tmp_buf, len);
2.write(socket, tmp_buf, len);

以上兩行程式碼是傳統的read/write方式進行檔案到socket的傳輸。

當需要對一個檔案進行傳輸的時候,其詳細流程細節例如以下:

  1.呼叫read函式,檔案資料被copy到核心緩衝區

  2.read函式返回。檔案資料從核心緩衝區copy到使用者緩衝區

  3.write函式呼叫。將檔案資料從使用者緩衝區copy到核心與socket相關的緩衝區。

  4.資料從socket緩衝區copy到相關協議引擎。

以上細節是傳統read/write方式進行網路檔案傳輸的方式,我們能夠看到,在這個過程其中,檔案資料實際上是經過了四次copy操作:

    硬碟-->核心buf-->使用者buf-->socket相關緩衝區(核心)-->協議引擎

2.新方式sendfile

  而sendfile系統呼叫則提供了一種降低以上多次copy。提升檔案傳輸效能的方法。

  Sendfile系統呼叫是在2.1版本號核心時引進的:

   sendfile(socket,file,len);

   執行流程如下:

    1.sendfile系統呼叫,檔案資料被copy至核心緩衝區

    2.再從核心緩衝區copy至核心中socket相關的緩衝區

    3.最後在socket相關的緩衝區copy到協議引擎

 

   相較傳統read/write方式,2.1.版本號核心引進的sendfile已經降低了核心緩衝區到user緩衝區。再由user緩衝區到socket相關緩衝區的檔案copy,而在核心版本號2.4之後,檔案描述符結果被改變,sendfile實現了更簡單的方式,系統呼叫方式仍然一樣,細節與2.1版本號的不同之處在於,當檔案資料被拷貝到核心資料緩衝區時,不再將全部資料copy到socket相關的緩衝區,而是隻將記錄資料位置和長度相關的資料儲存到socket相關的快取,而實際資料將由DMA模組直接傳送到協議引擎,再次降低了一次copy操作。