<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-86  評論-33  文章-0  trackbacks-0

    我們平時通過網(wǎng)絡發(fā)送文件時會用到的兩個系統(tǒng)調(diào)用:
    read(file, tmp_buf, len);
    write(socket, tmp_buf, len);

    調(diào)用過程示意圖如下:

    在用戶空間調(diào)用 read() 讀取文件時發(fā)生兩次內(nèi)存拷貝:

    1. DMA引擎將文件讀取到內(nèi)核的文件緩沖區(qū)
    2. 調(diào)用返回用戶空間時將內(nèi)核的文件緩沖區(qū)的數(shù)據(jù)復制到用戶空間的緩沖區(qū)

    接著調(diào)用 write() 把數(shù)據(jù)寫入 socket 時,又發(fā)生了兩次內(nèi)存拷貝:

    1. 將用戶空間的緩沖區(qū)的數(shù)據(jù)復制到內(nèi)核的 socket 緩沖區(qū)
    2. 將內(nèi)核 socket 緩沖區(qū)的數(shù)據(jù)復制到網(wǎng)絡協(xié)議引擎

    也就是說,在整個文件發(fā)送的過程中,發(fā)生了四次內(nèi)存拷貝。
    然后,數(shù)據(jù)讀取到用戶空間后并沒有做過任何加工處理,因此通過網(wǎng)絡發(fā)送文件時,根本沒有必要把文件內(nèi)容復制到用戶空間。

    于是引入了 mmap():
    tmp_buf = mmap(file, len);
    write(socket, tmp_buf, len);

    調(diào)用過程示意圖:

    1. 調(diào)用 mmap() 時會將文件直接讀取到內(nèi)核緩沖區(qū),并把內(nèi)核緩沖區(qū)直接共享到用戶空間
    2. 調(diào)用 write() 時,直接將內(nèi)核緩沖區(qū)的數(shù)據(jù)復制到網(wǎng)絡協(xié)議引擎

    這樣一來,就少了用戶空間和內(nèi)核空間之間的內(nèi)存復制了。
    這種方式會有個問題,當前進程在調(diào)用 write() 時,另一個進程把文件清空了,程序就會報出 SIGBUS 類型錯誤。

    Linux Kernel 2.1 引進了 sendfile(),只需要一個系統(tǒng)調(diào)用來實現(xiàn)文件發(fā)送。
    sendfile(socket, file, len);

    調(diào)用過程示意圖:

    1. 調(diào)用 sendfile() 時會直接在內(nèi)核空間把文件讀取到內(nèi)核的文件緩沖區(qū)
    2. 將內(nèi)核的文件緩沖區(qū)的數(shù)據(jù)復制到內(nèi)核的 socket 緩沖區(qū)中
    3. 將內(nèi)核的 socket 緩沖區(qū)的數(shù)據(jù)復制到網(wǎng)絡協(xié)議引擎

    從性能上看,這種方式只是少了一個系統(tǒng)調(diào)用而已,還是做了3次拷貝操作。

    Linux Kernel 2.4 改進了 sendfile(),調(diào)用接口沒有變化:
    sendfile(socket, file, len);

    調(diào)用過程示意圖:

    1. 調(diào)用 sendfile() 時會直接在內(nèi)核空間把文件讀取到內(nèi)核的文件緩沖區(qū)
    2. 內(nèi)核的 socket 緩沖區(qū)中保存的是當前要發(fā)送的數(shù)據(jù)在內(nèi)核的文件緩沖區(qū)中的位置和偏移量
    3. DMA gather copy 將內(nèi)核的文件緩沖區(qū)的數(shù)據(jù)復制到網(wǎng)絡協(xié)議引擎

    這樣就只剩下2次拷貝啦。

    在許多 http server 中,都引入了 sendfile 的機制,如 nginx、lighttpd 等,它們正是利用 sendfile() 這個特性來實現(xiàn)高性能的文件發(fā)送的。

    posted on 2011-12-29 21:32 Derek.Guo 閱讀(712) 評論(0)  編輯  收藏 所屬分類: Linux/Unix
    MSN:envoydada@hotmail.com QQ:34935442
    主站蜘蛛池模板: 免费网站观看WWW在线观看| AV大片在线无码永久免费| 亚洲国产精品国自产电影| 一色屋成人免费精品网站 | 国产亚洲精品bv在线观看| 在线观看无码的免费网站| WWW国产成人免费观看视频| 亚洲精品成人久久| 在线观看亚洲免费视频| 久久国产精品成人免费| 中国亚洲呦女专区| 亚洲精品乱码久久久久久按摩| 亚洲一区二区三区免费观看 | 99re在线免费视频| 日韩亚洲翔田千里在线| 久久精品国产亚洲av麻| 国产精品无码一二区免费| 少妇无码一区二区三区免费| 亚洲av无码专区在线电影天堂| 国产亚洲综合一区柠檬导航| 日韩免费福利视频| 1000部啪啪毛片免费看| 丁香六月婷婷精品免费观看| 亚洲国产成人99精品激情在线| 亚洲精品二区国产综合野狼 | 亚洲男人天堂2018av| 亚洲av无码乱码国产精品fc2 | 亚洲人成人无码.www石榴| 亚洲91av视频| 国产精品亚洲高清一区二区| 欧美最猛性xxxxx免费| 午夜影院免费观看| 成年免费a级毛片| 亚洲乱妇老熟女爽到高潮的片| 久久精品蜜芽亚洲国产AV | 亚洲av无码片vr一区二区三区| 久久久无码精品亚洲日韩蜜臀浪潮| 亚洲高清最新av网站| 日韩毛片无码永久免费看| 国产99视频精品免费观看7| 日韩精品无码专区免费播放|