socket_IO模型

1 背景知識

1.1 用戶空間和內核空間

好比32位系統,尋址空間是4G。內存分爲用戶空間和內核空間,內核空間僅供內核使用,用戶空間給各個進程使用。os的核心是內核,只有內核能夠訪問被保護的內存空間。爲了保證進程沒法直接操做內核 ,在用戶空間的進程沒法訪問內核空間。linux

系統調用函數運行於內核態,可是向用戶態開放接口。網絡

對於磁盤,網卡等設備,進程都沒法直接訪問,因此相關數據都用通過系統調用。socket

1.2 進程阻塞

正在執行的進程,因爲期待的事件未發生,好比io操做未完成,新數據未到達,就由系統自動執行阻塞,由運行狀態變爲阻塞狀態。因此,進程的阻塞是自身的自動行爲,只有處於運行狀態(獲取cpu時間片)的進程才能轉爲阻塞狀態。而且處於阻塞狀態的進程不佔用cpu。函數

1.3 文件描述符(句柄)

fd是指向具體文件的一個引用。spa

fd是一個非負整數。當進程打開一個新文件或者socket,系統就爲該文件分配一個fd,用來標識這個文件,這個分配的數字從0開始。系統默認狀況下,限制每一個進程能打來的文件爲1024。3d

1.4 標準io

在標準io機制中,在內核中有頁緩衝(內核高速緩衝),在用戶空間有流緩衝。指針

對於讀操做,數據首先被讀到頁緩衝(當頁緩衝中沒有該數據),而後再拷貝到進程的內存地址。blog

對於寫操做,數據先被寫到流緩衝,而後將屢次寫操做一次性寫到頁緩衝(減小系統調用),頁緩衝再將屢次寫操做一次性寫到磁盤(提升磁盤io效率)接口

 

2  linux中的幾種IO模型

網絡io的本質是socket的讀取。對於一次網絡io請求,有兩個階段:進程

  a 等待對端傳遞的數據就緒,就緒就拷貝到系統內核緩衝區,若是沒有就緒就一直等待就緒。

  b 將內核緩衝區中的數據拷貝到進程的地址空間中。

2.1 bio

 

阻塞io是最經常使用的socket模型,而且默認狀況下,全部socket都是阻塞的。

首先,進程要請求網絡數據時,使用recvfrom系統調用函數,而後系統調用從用戶空間轉移到內核空間運行。在內核空間等待對端數據報的到達,到達後內核空間的緩衝區後,把數據報拷貝到用戶空間應用的緩衝地址。這個過程完成後,就返回獲取成功給進程,進程沒有延遲,開始處理數據報。

整個過程當中,進程都是自我阻塞的,在等待數據就緒的過程當中,進程只能等待,沒法做其餘事情。好處是數據一就緒,進程就立刻能夠進行下一步的處理。

2.2 nio

在非阻塞模型中,當系統調用發現內核空間中未準備好數據,則直接返回一個error。進程會週期性輪訓,詢問內核空間是否準備好好數據。在此期間,進程不會等待(就是非阻塞)。

相對於阻塞模型,非阻塞模型釋放了進程,能夠同時處理其餘信息。但因爲是週期性輪訓,進程就不會在第一時間知道網路數據已準備好,因此增長了延遲。

但若是進程要處理多個socket,非阻塞模型老是比阻塞模型效率更高。

2.3 mio

 

就是用select、epoll、poll,將多個socket的文件描述符傳給內核,讓內核去監聽它們是否就緒。

當用戶進程調用 select,整個進程就被阻塞,當任何一個socket的數據在內核中 準備好了,select就會將可讀條件返回。而後進程使用系統調用,將數據拷貝到用戶空間(這一步就至關於bio)。

nio是進程主動去詢問多個socket的數據在內核中是否準備好,而mio是採用select去實時監聽多個socket在內核中的數據是否準備好。

 2.4 aio

進程使用aio_read函數將socket文件描述符,緩衝區指針、緩衝區大小和文件偏移傳遞給內核,而且告訴內核等數據準備好後直接傳給aio_read中。

進程不阻塞,數據準備好後,不須要進程再經過系統調用去讀。

2.5 比較

bio,nio,mio,在數據拷貝到用戶空間這個階段進程會被阻塞,屬於同步模型。

aio在這個階段進程不被阻塞

相關文章
相關標籤/搜索