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

Linux Sendfile 的優勢

硬盤 數據 pos article 詳細 write 操作 con 網絡

Sendfile 函數在兩個文件描寫敘述符之間直接傳遞數據(全然在內核中操作,傳送),從而避免了內核緩沖區數據和用戶緩沖區數據之間的拷貝,操作效率非常高,被稱之為零拷貝。

Sendfile 函數的定義例如以下:

#include<sys/sendfile.h>

ssize_t sendfile(int out_fd,int in_fd,off_t*offset,size_t count);

傳統方式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相關緩沖區(內核)—>協議引擎

新方式sendfile

而sendfile系統調用則提供了一種降低以上多次copy。提升文件傳輸性能的方法。

Sendfile系統調用是在2.1版本號內核時引進的:

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操作。

Linux Sendfile 的優勢