<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一文讀懂零拷貝技術(shù)

          共 1526字,需瀏覽 4分鐘

           ·

          2021-04-06 16:21

          零拷貝技術(shù) 是編寫高性能服務(wù)器的一個(gè)關(guān)鍵技術(shù),在介紹 零拷貝技術(shù) 前先說明一下 用戶空間內(nèi)核空間。

          用戶空間

          通俗的說,用戶空間 就是運(yùn)行著用戶編寫的應(yīng)用程序的虛擬內(nèi)存空間。在32位的操作系統(tǒng)中,每個(gè)進(jìn)程都有 4GB 獨(dú)立的虛擬內(nèi)存空間,而 0 ~ 3GB 的虛擬內(nèi)存空間就是用戶空間 。

          內(nèi)核空間

          內(nèi)核空間 就是運(yùn)行著操作系統(tǒng)代碼的虛擬內(nèi)存空間,而 3GB ~ 4GB 的虛擬內(nèi)存空間就是內(nèi)核空間。

          圖 1 展示了 用戶空間內(nèi)核空間 在進(jìn)程虛擬內(nèi)存空間所在的位置:

          發(fā)送文件

          為什么要介紹 用戶空間內(nèi)核空間 呢?

          我們先來回憶一下,服務(wù)端發(fā)送一個(gè)文件給客戶端一般需要進(jìn)行什么操作。一般來說,服務(wù)端發(fā)送一個(gè)文件給客戶端的步驟如下:

          • 首先需要調(diào)用 read 讀取文件的數(shù)據(jù)到用戶空間緩沖區(qū)中。

          • 然后再調(diào)用 write 把緩沖區(qū)的數(shù)據(jù)發(fā)送給客戶端 Socket。

            偽代碼如下:

          while ((n = read(file, buf, 4069)) > 0) {    write(sock, buf , n);}

          在上面的過程中,調(diào)用了 readwrite 兩個(gè)系統(tǒng)調(diào)用。read 系統(tǒng)調(diào)用是從文件中讀取數(shù)據(jù)到用戶空間的緩沖區(qū)中,所以調(diào)用 read 時(shí)需要從內(nèi)核空間復(fù)制數(shù)據(jù)到用戶空間,如圖 2 所示:

          圖2 就是數(shù)據(jù)的復(fù)制過程,首先會(huì)從文件中讀取數(shù)據(jù)到內(nèi)核的 頁緩存(page cache),然后再從頁緩存中復(fù)制到用戶空間的緩沖區(qū)中。

          而當(dāng)調(diào)用 write 系統(tǒng)調(diào)用把用戶空間緩沖區(qū)中的數(shù)據(jù)發(fā)送到客戶端 Socket 時(shí),首先會(huì)把緩沖區(qū)的數(shù)據(jù)復(fù)制到內(nèi)核的 Socket 緩沖區(qū)中,網(wǎng)卡驅(qū)動(dòng)會(huì)把 Socket 緩沖區(qū)的數(shù)據(jù)發(fā)送出去,如圖 3 所示:

          從上圖可以看出,服務(wù)端發(fā)送文件給客戶端的過程中需要進(jìn)行兩次數(shù)據(jù)復(fù)制,第一次是從內(nèi)核空間的頁緩存復(fù)制到用戶空間的緩沖區(qū),第二次是從用戶空間的緩沖區(qū)復(fù)制到內(nèi)核空間的 Socket 緩沖區(qū)。

          仔細(xì)觀察我們可以發(fā)現(xiàn),上圖中的頁緩存其實(shí)可以直接復(fù)制到 Socket 緩沖區(qū),而不需要復(fù)制到用戶空間緩沖區(qū)的。如圖 4 所示:

          如上圖所示,不需要用戶空間作為數(shù)據(jù)中轉(zhuǎn)的技術(shù)叫 零拷貝技術(shù)。那么,我們可以通過哪個(gè)系統(tǒng)調(diào)用來實(shí)現(xiàn)上圖中的技術(shù)呢?答案就是 sendfile,我們來看看 sendfile 系統(tǒng)調(diào)用的原型:

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

          下面介紹一下 sendfile 各個(gè)參數(shù)的作用:

          • out_fd:數(shù)據(jù)接收方文件句柄(一般為 Socket 句柄)。

          • in_fd:數(shù)據(jù)提供方文件句柄(一般為文件句柄)。

          • offset:如果 offset 不為 NULL,表示從哪里開始發(fā)送數(shù)據(jù)的偏移量。

          • count:表示需要發(fā)送多少字節(jié)的數(shù)據(jù)。

          sendfile 發(fā)送數(shù)據(jù)的過程如圖 5 所示:

          對比圖 5 與 圖 3,我們發(fā)現(xiàn)使用 sendfile 可以減少一次系統(tǒng)調(diào)用,并且減少一次數(shù)據(jù)拷貝過程。

          總結(jié)

          本文主要通過 sendfile 系統(tǒng)調(diào)用來介紹 零拷貝技術(shù),但 零拷貝技術(shù) 不單只有 sendfile,如 mmapsplice直接I/O 等都是 零拷貝技術(shù) 的實(shí)現(xiàn),有興趣的可以參考 Linux 官方文檔或相關(guān)資料。



          瀏覽 46
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩人妻精品在线 | 国产麻豆91福利网站 | 日韩视频一区二区三区在线播放免费观看 | 青青草国产在线视频 | 91干在线视频 |