幾個(gè)概念
- 應(yīng)用程序: 一般指需要處理并發(fā)請(qǐng)求的服務(wù)端
- 文件句柄:一般指socket流
- 用戶(hù)態(tài):用戶(hù)進(jìn)程所運(yùn)行的空間,個(gè)人理解是當(dāng)前進(jìn)程的運(yùn)行環(huán)境和使用的系統(tǒng)資源
- 內(nèi)核態(tài):系統(tǒng)內(nèi)核,cpu調(diào)度,內(nèi)存管理,用戶(hù)態(tài)通過(guò)系統(tǒng)調(diào)用來(lái)使用內(nèi)核中的資源
- 監(jiān)聽(tīng)者:select、epoll叫做監(jiān)聽(tīng)者
IO多路復(fù)用需要解決什么問(wèn)題:
1,節(jié)省cpu資源
2,提高并發(fā)性能
要完成對(duì)IO多路復(fù)用需要做如下幾個(gè)事情:
1,用戶(hù)態(tài)怎么將文件句柄傳遞到內(nèi)核態(tài)
2,內(nèi)核態(tài)怎么判斷IO流可讀可寫(xiě)
3,內(nèi)核怎么通知監(jiān)控者IO流有可讀可寫(xiě)事件發(fā)生
4,監(jiān)控者如何找到可讀可寫(xiě)的IO流并傳遞給用戶(hù)態(tài)應(yīng)用程序
5,繼續(xù)循環(huán)時(shí)監(jiān)控者怎么重復(fù)上述步驟
select
阻塞當(dāng)前線(xiàn)程,以輪詢(xún)的方式對(duì)IO流進(jìn)行監(jiān)聽(tīng),如果存在可讀、可寫(xiě)事件,通知當(dāng)前被阻塞的線(xiàn)程,但是它會(huì)輪詢(xún)當(dāng)前所有的IO流,
select方法接收三個(gè)參數(shù),可讀列表,可寫(xiě)列表,異常列表,返回三個(gè)list
select方法會(huì)將客戶(hù)端socket請(qǐng)求重用戶(hù)態(tài)copy到內(nèi)核態(tài),在內(nèi)核中維護(hù)一個(gè)數(shù)組,并不停的輪訓(xùn)這個(gè)數(shù)組
當(dāng)輪訓(xùn)到數(shù)組元素中socket發(fā)生變化,可讀事件(客戶(hù)端連接,客戶(hù)端發(fā)送數(shù)據(jù)),可寫(xiě)事件(服務(wù)端返回?cái)?shù)據(jù)),就將可讀或可寫(xiě)的數(shù)據(jù)返回,并繼續(xù)輪詢(xún)
當(dāng)前進(jìn)程獲取到可讀/可寫(xiě)列表后,判斷是否客戶(hù)端類(lèi)型是否數(shù)據(jù)當(dāng)前socket類(lèi)型,并且處理請(qǐng)求,處理完請(qǐng)求后將數(shù)據(jù)socket放入可寫(xiě)列表中,再次發(fā)送給select函數(shù)
并不斷重復(fù)這個(gè)過(guò)程
epoll:
1,內(nèi)核態(tài)執(zhí)行系統(tǒng)調(diào)用 epoll_create在內(nèi)核創(chuàng)建專(zhuān)屬于epoll的高速cache區(qū),并在改緩沖區(qū)建立紅黑樹(shù)和就緒鏈表,用戶(hù)態(tài)傳入的文件句柄將被傳入到紅黑樹(shù)中
引用
多路復(fù)用適用于需要保持大量閑置(區(qū)別于計(jì)算密集型)長(zhǎng)連接的業(yè)務(wù)場(chǎng)景,例如聊天室。這樣的好處是能夠避免不斷的創(chuàng)建新線(xiàn)程,導(dǎo)致系統(tǒng)資源浪費(fèi)。需要注意,多路復(fù)用本質(zhì)上是復(fù)用單線(xiàn)程的,回調(diào)函數(shù)的執(zhí)行必然是有可能長(zhǎng)時(shí)間阻塞的,所以如果涉及到耗時(shí)的計(jì)算密集型任務(wù),則會(huì)大大降低系統(tǒng)處理其它連接的響應(yīng)速度。
線(xiàn)程池則適合短連接并發(fā)的情況,比如普通的web業(yè)務(wù)系統(tǒng),Tomcat的Servlet容器默認(rèn)選擇就是線(xiàn)程池(雖然3.0后支持異步,但一般情況下不常使用)。由于處理短連接的線(xiàn)程很快會(huì)退出,因此能夠充分發(fā)揮線(xiàn)程池復(fù)用線(xiàn)程的好處。
當(dāng)然,多路復(fù)用和線(xiàn)程池可以結(jié)合起來(lái)使用,效果也許更好,但代碼復(fù)雜度也會(huì)相應(yīng)提高,需要更好的設(shè)計(jì)。建議根據(jù)業(yè)務(wù)場(chǎng)景選擇相應(yīng)的技術(shù),避免過(guò)早優(yōu)化。
一點(diǎn)補(bǔ)充:很多人不知道協(xié)程該歸于哪個(gè)技術(shù)范疇。協(xié)程除了在用戶(hù)態(tài)通過(guò)棧切換實(shí)現(xiàn)控制流的切換以外,還通常將多路復(fù)用和線(xiàn)程池結(jié)合起來(lái)。比如go語(yǔ)言?xún)?nèi)置的協(xié)程就是在多線(xiàn)程的基礎(chǔ)上實(shí)現(xiàn)了一套調(diào)度策略,調(diào)度策略的實(shí)現(xiàn)建立在操作系統(tǒng)內(nèi)核提供的IO多路復(fù)用技術(shù)之上,同時(shí)go語(yǔ)言參考計(jì)算機(jī)硬件情況自動(dòng)將協(xié)程綁定在若干個(gè)系統(tǒng)線(xiàn)程之上,從而實(shí)現(xiàn)資源的高效率利用。
參考文章:
浙公網(wǎng)安備 33010602011771號(hào)