BIO、NIO、epoll、AIO

早期BIO ,blockingIO,阻塞IO。Linux下一切皆文件,socket即讀文件描述符(fd)。當建立多個連接時,如下圖。

例如fd 8 的client連接一直沒返回,導致 read  fd8會進行阻塞,一直等待返回。read fd9連接無法進行處理。

 

由於BIO 導致阻塞,進而演變成NIO

開始進入NONBLOCK時代,非阻塞。還是多個連接。

非阻塞了,當多個連接來時,進行while 循環,循環調用 fd8 fd9 read,判斷有沒有返回,有就處理,沒有繼續循環。

 

解決了BIO的問題,但是問題又來了。如果有1000個連接,就需要不斷地循環1000,從fd1 到fd1000,效率多低。

進而演變內核發展,提供 select 調用。 select接口開始,不用做循環了,直接把fd1到fd1000全部傳給select,進行監控,直到有一個或多個的返回,將有返回的fd描述符傳給線程去read對應的描述符返回信息。即多路複用NIO時代

 

雖然進入了多路複用,但是過程很複雜,需要調用select,然後根據返回再去read。尤其是1000個描述符需要從用戶態拷貝給select。

內核發展出epoll,用戶空間可以調用epoll的create時,內核返回一個epfd(epoll的描述符),當用戶空間有一個連接進來後,將連接交給epoll描述符,同時調用epoll的wait(),epoll會準備一個共享空間mmap,只需要維護一個紅黑樹,連接都放到紅黑樹裏面。共享空間裏面增刪改由內核完成,用戶空間和內核雙方都可以查詢。當共享空間有連接返回後,wait()就可以返回了,從阻塞變成不阻塞,取出到達的那些描述符,單獨去read。

相當於用戶空間註冊一個連接到內核的epoll共享空間中,連接有返回後進行回調,由內核通知用戶空間,再去read描述符。

mmap:共享空間。由內核實現。相當於用戶態和內核態之間出現了一個共享空間。

 

AIO

AIO:Asynchronous IO 是 NIO 的升級,也叫 NIO2,實現了異步非堵塞 IO ,異步 IO 的操作基於事件和回調機制。但是NIO的IO行爲還是同步的

對AIO來說,則更加進了一步,它不是在IO準備好時再通知線程,而是在IO操作已經完成後,再給線程發出通知。因此AIO是不會阻塞的,此時我們的業務邏輯將變成一個回調函數,等待IO操作完成後,由系統自動觸發。

 

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