一、基礎(chǔ)概念
1.內(nèi)存分類
內(nèi)存分為兩部分,一部分分給內(nèi)核使用,另一部分分給用戶使用。為什么要這么劃分,因?yàn)閮?nèi)核作為操作系統(tǒng)的核心,他理論上擁有更大的權(quán)限以及應(yīng)該受到更高級(jí)別的保護(hù),所以它使用的內(nèi)存應(yīng)該單獨(dú)區(qū)分出來(lái),以防app對(duì)其造成不必要的傷害。
元帥擁有自己的一支禁衛(wèi)軍,這支禁衛(wèi)軍非常值得信賴,完全不擔(dān)心被策反(病毒感染)。相反,普通軍隊(duì)(用戶內(nèi)存)就比較容易被策反。這就是擁有一套自己的禁衛(wèi)軍的必要性。
2.進(jìn)程切換
內(nèi)核是整個(gè)系統(tǒng)的中心,所以他擁有對(duì)線程操作的權(quán)利,有能力掛起,也有能力恢復(fù)。
在對(duì)線程進(jìn)行切換的時(shí)候,需要保存各種現(xiàn)場(chǎng)信息,為了方便對(duì)進(jìn)程進(jìn)行管理,將相關(guān)的數(shù)據(jù)、命令等進(jìn)行封裝,數(shù)據(jù)結(jié)構(gòu)稱之為PCB(process control block)。
當(dāng)內(nèi)核將一個(gè)進(jìn)程在CPU上掛起,喚醒另一個(gè)進(jìn)程執(zhí)行的時(shí)候,需要處理大量的上下文切換,總之就是很繁瑣,很復(fù)雜,很蛋疼。
元帥是所有軍隊(duì)的統(tǒng)領(lǐng),擁有調(diào)度小分隊(duì)是否繼續(xù),是否暫停,是否回復(fù)當(dāng)前任務(wù)的權(quán)利。
當(dāng)更換小分隊(duì)執(zhí)行任務(wù)的狀態(tài)的時(shí)候,需要告訴小分隊(duì)的頭頭,小分隊(duì)的leader,小分隊(duì)的供給部隊(duì),小分隊(duì)的武器提供部隊(duì),小分隊(duì)的監(jiān)督部隊(duì),總之就是需要告訴方方面面。為了方便管理,就把這些部分統(tǒng)一管理起來(lái),形成一個(gè)單元進(jìn)行統(tǒng)一的操作,而不是東一榔頭,西一棒槌,高效一些。這個(gè)單元就是PCB。
3.進(jìn)程的阻塞
當(dāng)進(jìn)程的要求獲得的一部分資源沒有到位的時(shí)候,就會(huì)導(dǎo)致當(dāng)前進(jìn)程無(wú)法繼續(xù)執(zhí)行,這個(gè)時(shí)候,進(jìn)程會(huì)自動(dòng)執(zhí)行阻塞原語(yǔ),并且釋放掉正在占用的CPU資源。
當(dāng)小分隊(duì)執(zhí)行刺殺/綁架/解救任務(wù)的時(shí)候,發(fā)現(xiàn)武器資源/食品資源等資源沒有到位,就只能暫停掉當(dāng)前任務(wù),并且把元首分配的任務(wù)符(CPU)還給元首,等資源到位了,再聽元首的安排。
元首的任務(wù)符是有限的,因?yàn)樵椎墓芾砟芰κ怯邢薜模荒軣o(wú)限制的增加正在執(zhí)行任務(wù)的個(gè)數(shù),這樣子的話,容易導(dǎo)致任務(wù)失控。
4.文件描述符
文件描述符是一個(gè)非負(fù)的索引值,是內(nèi)核所維護(hù)的關(guān)于一個(gè)進(jìn)程操作一個(gè)文件的一份記錄。
資源物品清單,是元首在分配每個(gè)行動(dòng)的時(shí)候,為每個(gè)行動(dòng)記錄分配了怎樣的人員、多少的裝備和武器,所以也可以理解為任務(wù)詳情表。也就是檔案,比如某某年,某某月,派出了某某人手,帶了哪些物資,刺殺了哪位要員。
5.緩存IO
緩存IO也稱為標(biāo)準(zhǔn)IO,操作系統(tǒng)通過(guò)流方式讀取文件時(shí),一般會(huì)先把文件讀取到頁(yè)緩存中,而頁(yè)緩存在內(nèi)核內(nèi)存中,當(dāng)應(yīng)用使用的時(shí)候,再把數(shù)據(jù)從內(nèi)核內(nèi)存讀取到應(yīng)用內(nèi)存。所以缺點(diǎn)很明顯,數(shù)據(jù)需要進(jìn)行多次復(fù)制,且占用寶貴的內(nèi)存資源,消耗CPU。
文件IO流,就可以理解為繳獲的物資啊、情報(bào)啊、等等進(jìn)項(xiàng)。有了這些好東西,當(dāng)然要先緊著元首使用了,元首的優(yōu)先級(jí)最高嘛,所以要先把繳獲的物資等等,放到內(nèi)核內(nèi)存中,元首先處理,處理完了,再留給下級(jí)處理。
二、IO模型
正如上面所言,一個(gè)應(yīng)用程序進(jìn)程如果需要獲取數(shù)據(jù),
第一步:等待數(shù)據(jù)傳輸?shù)絻?nèi)核內(nèi)存中。
第二步:等待數(shù)據(jù)從內(nèi)核內(nèi)存中,copy到進(jìn)程中。
因?yàn)橐陨蟽蓚€(gè)步驟,所以產(chǎn)生了五種態(tài)度
- 阻塞IO
- 非阻塞IO
- I/O多路復(fù)用
- 異步IO
- 信號(hào)驅(qū)動(dòng)IO
1. 阻塞IO
當(dāng)數(shù)據(jù)從流中,拷貝到內(nèi)核內(nèi)存,再?gòu)膬?nèi)核內(nèi)存拷貝到應(yīng)用程序內(nèi)存。這兩段時(shí)間內(nèi),進(jìn)程都會(huì)主動(dòng)選擇阻塞。
這個(gè)小分隊(duì)比較無(wú)自主能動(dòng)性且不積極,元首不給命令就不會(huì)干點(diǎn)別的準(zhǔn)備動(dòng)作,迂腐,垃圾。
2. 非阻塞IO
進(jìn)程會(huì)輪詢內(nèi)核內(nèi)存,數(shù)據(jù)是否準(zhǔn)備ok。ok的話返回OK,不ok的話返回error。當(dāng)進(jìn)程收到error的時(shí)候,就繼續(xù)輪詢內(nèi)核內(nèi)存...子子孫孫無(wú)窮盡
非阻塞IO可煩人了,一直在不斷地問(wèn)問(wèn)問(wèn),雖然能顯出你積極,但是也可煩人消耗性能。
3. 多路復(fù)用IO
首先強(qiáng)調(diào)一點(diǎn),多路復(fù)用IO是一個(gè)進(jìn)程對(duì)應(yīng)多個(gè)IO。進(jìn)程首先會(huì)調(diào)用select,然后選擇阻塞。調(diào)用select的目的就是,當(dāng)對(duì)應(yīng)的IO中有任何一個(gè)完成拷貝數(shù)據(jù)到內(nèi)核內(nèi)存的時(shí)候,就會(huì)return readable給進(jìn)程,然后進(jìn)程繼續(xù)選擇block,等到數(shù)據(jù)從內(nèi)核內(nèi)存拷貝到應(yīng)用程序內(nèi)存。
其實(shí)當(dāng)IO連接數(shù)比較低的時(shí)候,多路復(fù)用IO的性能還可能比不上Block IO,但是multiplexing IO天生就是處理大場(chǎng)面的,處理多IO連接的場(chǎng)景。當(dāng)IO數(shù)較大時(shí),能夠使得一個(gè)進(jìn)程處理多個(gè)IO連接。棒棒噠。
類似于統(tǒng)籌,比如你要看十個(gè)視頻,每個(gè)視頻都有廣告。當(dāng)你看完一個(gè)視頻,再去看下一個(gè)視頻,你需要看十次廣告。但是如果你先把所有的視頻都點(diǎn)開,讓廣告同時(shí)播放,這樣子你就只用浪費(fèi)一個(gè)多廣告的時(shí)間,就可以無(wú)廣告的看完所有的十個(gè)視頻,效率立判高下。
4. 異步IO
進(jìn)程會(huì)發(fā)起aio_read命令,然后會(huì)立刻返回,這樣進(jìn)程不會(huì)選擇阻塞,而是繼續(xù)執(zhí)行。內(nèi)核在收到aio_read命令后,會(huì)主動(dòng)的把數(shù)據(jù)進(jìn)行兩次拷貝,然后通過(guò)signal告訴進(jìn)程,完成了。
這樣的進(jìn)程就相當(dāng)于高級(jí)小分隊(duì),任務(wù)比較忙耽誤不得,并且有一個(gè)秘書負(fù)責(zé)信息的接受,秘書接受完信息后,會(huì)通知小分隊(duì)。而在這期間,小分隊(duì)繼續(xù)執(zhí)行其他任務(wù)。
注意
同步異步IO指的是數(shù)據(jù)從內(nèi)核內(nèi)存拷貝到用戶內(nèi)存的過(guò)程中,進(jìn)程的狀態(tài)。所以 block IO、non-block IO、multiplexing IO都屬于同步IO,只有asynchronous IO,屬于真正的異步IO。