首先明白:操作系統(tǒng)將內(nèi)存空間分為:用戶空間和內(nèi)核空間坎怪,用戶空間是普通應用程序可以去訪問的內(nèi)存空間性含,內(nèi)核空間是操作系統(tǒng)內(nèi)核去訪問的內(nèi)存空間**
那這時候座哩,我們也要明白什么是用戶態(tài),什么是內(nèi)核態(tài)
內(nèi)核態(tài):進程處于內(nèi)核空間的時候,權(quán)限幾乎不受限制赁豆,權(quán)限包括:進程管理,內(nèi)存管理冗美,文件管理
那如果應用程序也想進行進程管理魔种,只能去請求系統(tǒng)調(diào)用,請求操作系統(tǒng)去幫他完成進程管理
io操作必須在內(nèi)核空間下完成
應用程序請求系統(tǒng)調(diào)用后粉洼,操作系統(tǒng)會完成兩個操作:
1:等待io操作處理好數(shù)據(jù)
2:將數(shù)據(jù)從內(nèi)核空間復制到應用空間
1节预、BIO阻塞式IO
同步阻塞 IO 模型中,應用程序發(fā)起 read 調(diào)用后属韧,會一直阻塞徽鼎,直到內(nèi)核把數(shù)據(jù)拷貝到用戶空間扼劈。
如圖所示BIO硼砰,應用程序會一直在等待內(nèi)核將數(shù)據(jù)返回
2碎罚、NIO 非阻塞式IO
同步非阻塞 IO 模型中,應用程序會一直發(fā)起 read 調(diào)用,等待數(shù)據(jù)從內(nèi)核空間拷貝到用戶空間的這段時間里拙泽,線程依然是阻塞的淌山,直到在內(nèi)核把數(shù)據(jù)拷貝到用戶空間
如圖所示NIO是非阻塞的,會不停的發(fā)出IO請求顾瞻,不斷的輪詢來請求數(shù)據(jù)泼疑,但是在該過程中,依然是阻塞的
3朋其、IO多路復用
用戶態(tài)會先用select或poll去通知內(nèi)核態(tài)去準備數(shù)據(jù)王浴,數(shù)據(jù)準備好了脆炎,再去發(fā)起read調(diào)用
select梅猿、poll、epoll介紹
重點介紹:select秒裕,poll袱蚓,epoll**
select機制提供一個fd(file-description)_set數(shù)據(jù)結(jié)構(gòu),是一個long型的數(shù)據(jù)結(jié)構(gòu)几蜻,每一個元素指向一個file-description喇潘,文件描述符是什么?open(file梭稚,path)颖低,這個函數(shù)會返回一個獨特值,標志該文件也被打開弧烤,就是open函數(shù)的返回值忱屑,調(diào)用select(),系統(tǒng)會根據(jù)io是否準備好數(shù)據(jù)暇昂,去更新fd_set中內(nèi)容莺戒,通知線程哪一個文件可讀
select的缺點:1:fd_set集合需要從用戶空間copy到內(nèi)核空間,開銷大
2:需要對fd_set遍歷
3:fd_set的大小1024是固定的
poll和select基本原理一樣急波,區(qū)別:poll的fd_set大小沒有限制从铲,都是去遍歷數(shù)組或鏈表,看哪個文件是可以用的
epoll(最先進):底層用hash表來實現(xiàn)對文件是否可讀狀態(tài)的更新澄暮,利用回調(diào)名段,fd準備就緒后,就把fd放在readyList里
**解決了1和2的問題:hash表直接放在內(nèi)核泣懊,hash表查找不用遍歷吉嫩,比較快