Linux Sendfile的优势
Sendfile函數(shù)在兩個(gè)文件描寫敘述符之間直接傳遞數(shù)據(jù)(全然在內(nèi)核中操作,傳送),從而避免了內(nèi)核緩沖區(qū)數(shù)據(jù)和用戶緩沖區(qū)數(shù)據(jù)之間的拷貝,操作效率非常高,被稱之為零拷貝。
Sendfile函數(shù)的定義例如以下:
#include <sys/sendfile.h> ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);1.傳統(tǒng)方式read/write send/recv
在傳統(tǒng)的文件傳輸里面(read/write方式),在實(shí)現(xiàn)上事實(shí)上是比較復(fù)雜的,需要經(jīng)過(guò)多次上下文的切換。我們看一下例如以下兩行代碼:
1.read(file, tmp_buf, len); 2.write(socket, tmp_buf, len);以上兩行代碼是傳統(tǒng)的read/write方式進(jìn)行文件到socket的傳輸。
當(dāng)需要對(duì)一個(gè)文件進(jìn)行傳輸?shù)臅r(shí)候,其詳細(xì)流程細(xì)節(jié)例如以下:
? 1.調(diào)用read函數(shù),文件數(shù)據(jù)被copy到內(nèi)核緩沖區(qū)
? 2.read函數(shù)返回。文件數(shù)據(jù)從內(nèi)核緩沖區(qū)copy到用戶緩沖區(qū)
? 3.write函數(shù)調(diào)用。將文件數(shù)據(jù)從用戶緩沖區(qū)copy到內(nèi)核與socket相關(guān)的緩沖區(qū)。
? 4.數(shù)據(jù)從socket緩沖區(qū)copy到相關(guān)協(xié)議引擎。
以上細(xì)節(jié)是傳統(tǒng)read/write方式進(jìn)行網(wǎng)絡(luò)文件傳輸?shù)姆绞?#xff0c;我們能夠看到,在這個(gè)過(guò)程其中,文件數(shù)據(jù)實(shí)際上是經(jīng)過(guò)了四次copy操作:
? ? 硬盤-->內(nèi)核buf-->用戶buf-->socket相關(guān)緩沖區(qū)(內(nèi)核)-->協(xié)議引擎
2.新方式sendfile
? 而sendfile系統(tǒng)調(diào)用則提供了一種降低以上多次copy。提升文件傳輸性能的方法。
? Sendfile系統(tǒng)調(diào)用是在2.1版本號(hào)內(nèi)核時(shí)引進(jìn)的:
? ?sendfile(socket,file,len);
? ?執(zhí)行流程如下:
? ? 1.sendfile系統(tǒng)調(diào)用,文件數(shù)據(jù)被copy至內(nèi)核緩沖區(qū)
? ? 2.再?gòu)膬?nèi)核緩沖區(qū)copy至內(nèi)核中socket相關(guān)的緩沖區(qū)
? ? 3.最后在socket相關(guān)的緩沖區(qū)copy到協(xié)議引擎
?
? ?相較傳統(tǒng)read/write方式,2.1.版本號(hào)內(nèi)核引進(jìn)的sendfile已經(jīng)降低了內(nèi)核緩沖區(qū)到user緩沖區(qū)。再由user緩沖區(qū)到socket相關(guān)緩沖區(qū)的文件copy,而在內(nèi)核版本號(hào)2.4之后,文件描述符結(jié)果被改變,sendfile實(shí)現(xiàn)了更簡(jiǎn)單的方式,系統(tǒng)調(diào)用方式仍然一樣,細(xì)節(jié)與2.1版本號(hào)的不同之處在于,當(dāng)文件數(shù)據(jù)被拷貝到內(nèi)核數(shù)據(jù)緩沖區(qū)時(shí),不再將全部數(shù)據(jù)copy到socket相關(guān)的緩沖區(qū),而是只將記錄數(shù)據(jù)位置和長(zhǎng)度相關(guān)的數(shù)據(jù)保存到socket相關(guān)的緩存,而實(shí)際數(shù)據(jù)將由DMA模塊直接發(fā)送到協(xié)議引擎,再次降低了一次copy操作。
總結(jié)
以上是生活随笔為你收集整理的Linux Sendfile的优势的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《深入理解NGINX 模块开发与架构解析
- 下一篇: 看完这篇,你应该知道什么是Linux了~