1 阻塞IO模型從字面來(lái)理解,就是調(diào)用時(shí)可能被阻塞, 什么叫阻塞,要知道一個(gè)進(jìn)程有N種狀態(tài),學(xué)過(guò)OS都知道 如果阻塞,就會(huì)把當(dāng)前進(jìn)程放在某個(gè)條件的阻塞隊(duì)列里。 直到條件滿足了,才會(huì)轉(zhuǎn)移此進(jìn)程進(jìn)入就緒隊(duì)列。 當(dāng)然,就緒隊(duì)列還有個(gè)優(yōu)先級(jí)的概念,就不扯遠(yuǎn)了。 阻塞IO. 1)調(diào)用API,比如 recvfrom,從用戶態(tài)進(jìn)入內(nèi)核態(tài)。 2) 內(nèi)核發(fā)現(xiàn)無(wú)數(shù)據(jù),將進(jìn)程信息節(jié)點(diǎn)插入阻塞隊(duì)列,等待數(shù)據(jù)。 3)進(jìn)程一直阻塞,阻塞,阻塞。 4)數(shù)據(jù)到達(dá),內(nèi)核拷貝數(shù)據(jù), 數(shù)據(jù)的流動(dòng)路徑是:網(wǎng)卡---socket內(nèi)核緩沖區(qū)---用戶的緩沖區(qū)。 5)拷貝完成后返回,我們就可以得到recvfrom的結(jié)果,成功/失敗。 2 非阻塞IO模型什么叫非阻塞,就是從用戶角度來(lái)說(shuō),函數(shù)立即可以得到結(jié)果:成功/失敗。 1)用戶調(diào)用recvfrom,內(nèi)核發(fā)現(xiàn)無(wú)數(shù)據(jù),立即返回結(jié)果。 2)用戶調(diào)用recvfrom,內(nèi)核發(fā)現(xiàn)無(wú)數(shù)據(jù),立即返回結(jié)果。 3)用戶調(diào)用recvfrom,內(nèi)核發(fā)現(xiàn)無(wú)數(shù)據(jù),立即返回結(jié)果。 4)用戶調(diào)用recvfrom,內(nèi)核發(fā)現(xiàn)有數(shù)據(jù),將數(shù)據(jù)從socket內(nèi)核緩沖區(qū)復(fù)制到 用戶緩沖區(qū),返回結(jié)果。 3 IO復(fù)用模型1)將多個(gè)需要監(jiān)聽(tīng)的fd給epoll,讓其監(jiān)控。 注意:epoll本身是阻塞的,可以設(shè)定時(shí)間。 2)epoll返回結(jié)果,用戶可以知道哪些fd可讀,可寫,有異常等。 3)剩下的就是用戶自己按需操作fd. 比如redis就是使用IO復(fù)用模型。 4)信號(hào)驅(qū)動(dòng)模型1)開(kāi)啟socket信號(hào)驅(qū)動(dòng)IO功能, 通過(guò)sigaction設(shè)置信號(hào)處理函數(shù)。 2)當(dāng)socket有數(shù)據(jù)時(shí),發(fā)生一個(gè)SIGIO信號(hào), 執(zhí)行之前的信號(hào)處理函數(shù)。 3)用戶邏輯放在信號(hào)處理函數(shù)里實(shí)現(xiàn)。 5)異步IO1)告知內(nèi)核啟動(dòng)某個(gè)操作,在內(nèi)核完成所有的操作(包括復(fù)制數(shù)據(jù)到用戶緩沖區(qū))后 通過(guò)信號(hào)機(jī)制通知用戶。 2)信號(hào)處理程序直接處理用戶緩沖區(qū)里的數(shù)據(jù),因?yàn)閿?shù)據(jù)已經(jīng)被內(nèi)核復(fù)制完畢。 與信號(hào)驅(qū)動(dòng)的區(qū)別是: 信號(hào)驅(qū)動(dòng)通過(guò)信號(hào)告知,可以啟動(dòng)某個(gè)操作了。 異步IO通知用戶:我連復(fù)制數(shù)據(jù)的步驟都替你完成了,用戶只需要處理即可。 總結(jié)一下:為什么會(huì)出現(xiàn)這么多的模型? 需求來(lái)源于需求,我們想想在開(kāi)發(fā)網(wǎng)絡(luò)程序時(shí),對(duì)一個(gè)socket需要關(guān)注哪些方面? 1)這個(gè)socket可讀,可寫,有異常? 2)有數(shù)據(jù)可操控時(shí),復(fù)制數(shù)據(jù)到用戶緩沖區(qū)。
下面是我對(duì)這幾種IO模型的理解
|
|