I/O模型&&零拷貝簡述

概要

用戶發起IO操作,一般就是兩個動作。

內核把網卡/磁盤的內容搬到內核空間(動作A),再把內核空間數據搬到用戶空間(動作B)。

 

主要有五種模型

  • 同步阻塞

這個比較簡單,就是用戶發起操作後 靜靜的等待AB完成。完全block住

  • 同步非阻塞

這個其實和同步阻塞相差不大。動作B也是完全阻塞模式,動作A階段 內核會直接告訴你沒好,上面那個是沒好不說 你等着。這個是輪訓去問,別問 問就是沒好。

  • 多路複用

這個也是阻塞的,好處是一個線程處理多個channel,數據到內核空間了, 通知用戶線程去做讀操作

類似一個代表,提大家等通知。boss workers

selector

selector內部維護了一個數據結構(bitmap),存儲已經接受的socket。複製一份交給內核去輪訓對應的socket集合是否有期待的事件發生。如果發生了 就會置位(用戶臺到內核態的複製) 然後交給用戶態完成事件的處理

 

epoller

epoll用紅黑樹存儲socket對象,用一個list維護socket發生的事件,用戶態只需要輪訓該隊列

 

區別

1.selector和poll的fd是用戶態創建,需要複製一份到內核態。內核態檢測到fd事件到來 再回傳到用戶態,用戶態進行遍歷。

epoll是在內核態創建fd,有fd事件把這個拷貝到用戶態

2.select和poll會遍歷所有的fd的隊列,epoll只會遍歷有事件發生的fd對應隊列

3.內核角度,fd數組在內核 都需要和硬件綁定 ,綁定很耗時。epoll的數組在內核中,綁定1次就好

 

  • 信號驅動

  • 異步

這個依賴操作系統了,就是發起後自己玩自己的,數據全部就緒 通知用戶線程。

具體的是用戶線程發read調用,註冊一個回調函數

 

零拷貝技術

主要有mmap和sendfile

mmap是用戶緩衝區和內核緩衝區 映射到同一個內存地址,java分配的堆外內存

 

sendfile

sendfile系統調用在兩個文件描述符之間直接傳遞數據(完全是內核中的操作),沒有用戶緩衝區和內核緩衝區拷貝的動作。

原理
sendfile() 系統調用利用 DMA 引擎將文件中的數據拷貝到操作系統內核緩衝區中,然後數據被拷貝到與 socket 相關的內核緩衝區中去。接下來,DMA 引擎將數據從內核 socket 緩衝區中拷貝到協議引擎中去。

sendfile() 系統調用不需要將數據拷貝或者映射到應用程序地址空間中去,所以 sendfile() 只是適用於應用程序地址空間不需要對所訪問數據進行處理的情況。因爲 sendfile 傳輸的數據沒有越過用戶應用程序 / 操作系統內核的邊界線,所以 sendfile () 也極大地減少了存儲管理的開銷。

簡單歸納上述的過程:

sendfile系統調用利用DMA引擎將文件數據拷貝到內核緩衝區,之後數據被拷貝到內核socket緩衝區中
DMA引擎將數據從內核socket緩衝區拷貝到協議引擎中
這裏沒有用戶態和內核態之間的切換,也沒有內核緩衝區和用戶緩衝區之間的拷貝,大大提升了傳輸性能。


原文鏈接:https://blog.csdn.net/SmallCatBaby/article/details/89877616

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章