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

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

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

    隨筆-86  評(píng)論-33  文章-0  trackbacks-0

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

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

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

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

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

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

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

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

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

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

    這樣一來(lái),就少了用戶空間和內(nèi)核空間之間的內(nèi)存復(fù)制了。
    這種方式會(huì)有個(gè)問(wèn)題,當(dāng)前進(jìn)程在調(diào)用 write() 時(shí),另一個(gè)進(jìn)程把文件清空了,程序就會(huì)報(bào)出 SIGBUS 類(lèi)型錯(cuò)誤。

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

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

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

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

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

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

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

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

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

    posted on 2011-12-29 21:32 Derek.Guo 閱讀(703) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): Linux/Unix
    MSN:envoydada@hotmail.com QQ:34935442
    主站蜘蛛池模板: 国内精品乱码卡1卡2卡3免费| 亚洲综合熟女久久久30p| 成年人视频在线观看免费| 97se亚洲综合在线| 国产成人亚洲毛片| 日本在线看片免费人成视频1000 | 免费夜色污私人影院网站电影| 亚洲熟妇无码八V在线播放| 日韩免费无码一区二区三区 | 永久黄网站色视频免费| 色噜噜亚洲精品中文字幕| 特级无码毛片免费视频| 亚洲综合色成在线播放| 亚洲乱人伦精品图片| 一二三四免费观看在线电影| 亚洲 暴爽 AV人人爽日日碰| 性做久久久久免费观看| 72pao国产成视频永久免费| 亚洲成AV人片在线观看WWW| 人妻丰满熟妇无码区免费 | 亚洲专区一路线二| 人成午夜免费视频在线观看| 亚洲中文字幕无码爆乳| 亚洲国产成人久久一区久久| a级片在线免费看| 亚洲一区二区三区亚瑟| 午夜国产羞羞视频免费网站| 久久精品免费一区二区三区| 国产精品亚洲午夜一区二区三区| 成人区精品一区二区不卡亚洲| 中国一级特黄的片子免费 | 亚洲视频在线观看网址| 一个人在线观看视频免费| 国产亚洲精品2021自在线| 亚洲精品国产精品乱码视色| 3d动漫精品啪啪一区二区免费| 亚洲AV无码一区二区乱孑伦AS| 人与动性xxxxx免费| 内射干少妇亚洲69XXX| 好爽…又高潮了毛片免费看| 国产99视频精品免费视频76|