零拷貝操作

零拷貝

在兩個文件描述符之間直接傳遞數據(完全在內核中操作),從而避免了內核緩衝區和用戶緩衝區之間的數據拷貝。

接下來,將介紹三個與零拷貝操作相關的函數,sendfile函數,splice函數和tee函數

首先,

sendfile函數

#include 《sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count );
in_fd參數是待讀出內容的文件描述符(in_fd必須是一個支持類似mmap函數描述符,即指向
真實的文件,不能是socket或管道)。
out_fd是待寫入內容的文件描述符(out_fd必須是一個socket)。
offset是指定讀入文件流的哪個位置開始讀,如果爲空,則默認的起始位置。
count參數指定在文件描述in_fd和out_fd之間傳遞的字節數。

函數成功返回傳輸的字節數;失敗返回-1並設置error.

splice函數

用於在兩個文件描述符之間移動數據,也是零拷貝操作。
#include <fcntl.h>
ssize_t splice( int fd_in, loff_t* off_in, int fd_out, loff_t* ff_out,
                size_t len, unsigned int flags );

這裏寫圖片描述

fd_out/off_out參數與fd_in/offin類似,用於輸出數據流。
len參數指定移動數據的長度。
flag參數用於控制數據如何移動。

這裏寫圖片描述

函數調用成功時返回移動字節的數量,返回0表示沒有數據需要移動(發生在從管道中讀取數據
而該管道沒有被寫入任何數據)。
失敗返回-1並設置error。

這裏寫圖片描述

tee函數

該函數是在兩個管道文件描述符之間複製數據。不消耗數據(源文件描述符上的數據仍可以用於後續的讀操作)

#include <fcntl.h>
ssize_t tee ( int fd_in, int fd_out, size_t len, unsigned int flags );
這裏的fd_in和fd_out必須是管道文件描述符
函數成功返回在兩個文件描述符之間複製的數據數量(字節數),0表示沒有複製任何數據,
失敗返回-1並設置errno.

參考資料:《Linux高性能服務器編程》

發佈了40 篇原創文章 · 獲贊 6 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章