2023-06-22 03:00:45 來源 : 面包芯語
在《Unix網(wǎng)絡(luò)編程》一書中提到了五種IO模型,分別是:阻塞IO、非阻塞IO、IO復(fù)用、信號驅(qū)動IO以及異步IO。本篇文章主要介紹IO的基本概念以及阻塞IO、非阻塞IO、IO復(fù)用三種模型,供大家參考學(xué)習(xí)。
(資料圖片僅供參考)
一、什么是IO
計算機(jī)視角理解IO:
對于計算機(jī)而言,任何涉及到計算機(jī)核心(CPU和內(nèi)存)與其他設(shè)備間的數(shù)據(jù)轉(zhuǎn)移的過程就是IO。IO對于計算機(jī)而言有兩層意思:
程序視角理解IO:
現(xiàn)代操作系統(tǒng)將空間劃分為用戶空間和內(nèi)核空間。
操作系統(tǒng)為了能夠正常平穩(wěn)地運(yùn)行下去,它是不會允許應(yīng)用程序隨意訪問計算機(jī)硬件部分,如內(nèi)存、硬盤、網(wǎng)卡,應(yīng)用程序必須通過操作系統(tǒng)提供的API來訪問,以達(dá)到安全的訪問控制。
總結(jié):IO對于應(yīng)用程序而言,強(qiáng)調(diào)的是通過向內(nèi)核發(fā)起系統(tǒng)調(diào)用完成對I/O的間接訪問。
應(yīng)用程序發(fā)起一次IO訪問分為兩個階段:
應(yīng)用程序發(fā)起一個系統(tǒng)調(diào)用(recvform),這個時候應(yīng)用程序會一直阻塞下去,直到內(nèi)核把數(shù)據(jù)準(zhǔn)備好,并將其從內(nèi)核復(fù)制到用戶空間,復(fù)制完成后返回成功提示,這個時候應(yīng)用程序才會繼續(xù)處理數(shù)據(jù)。
典型的阻塞I/0模型的例子為data=socket.read()
,如果內(nèi)核數(shù)據(jù)沒有準(zhǔn)備就緒,Socket線程就會一直阻塞在read()
中等待內(nèi)核數(shù)據(jù)就緒。
生活場景:某天,你跟你女朋友去奶茶店買奶茶,點(diǎn)完奶茶后后,由于你們不知道奶茶什么時候才能做好,所以你們就只能一直等著,其他什么事情也不能干。
從上圖可以看出, 非阻塞IO模型需要應(yīng)用進(jìn)程不斷地主動詢問內(nèi)核數(shù)據(jù)是否已準(zhǔn)備好了。
生活場景:你和你女朋友去奶茶店買奶茶,吸取了上一次的教訓(xùn),點(diǎn)完奶茶后順便去逛了逛商場。由于你們擔(dān)心會錯過取餐,所以你們就每隔一段時間就來問下服務(wù)員,你們的奶茶做好了沒有,來來回回好多回,若干次后,終于問到奶茶已經(jīng)準(zhǔn)備好了,然后你們就開心的喝了起來。
四、IO復(fù)用模型
非阻塞IO模型需要進(jìn)程不斷地輪詢發(fā)起recvform系統(tǒng)調(diào)用,就會有很多的線程不斷調(diào)用recvfrom 請求數(shù)據(jù),先不說服務(wù)器能不能扛得住這么多線程,就算扛得住那么很明顯這種方式是不是太浪費(fèi)資源了,線程是我們操作系統(tǒng)的寶貴資源,大量的線程用來去讀取數(shù)據(jù)了,那么就意味著能做其它事情的線程就會少。
例如:你是奶茶店的服務(wù)員,每個人點(diǎn)好奶茶后,每隔幾分鐘就來問你一次好了沒有,隨著問的人越來越多,你可能會開始懷疑人生。那么有沒有什么好的解決辦法呢?
答案:不需要所有進(jìn)程輪詢來發(fā)起recvform來查詢數(shù)據(jù)是否已經(jīng)準(zhǔn)備好了,而是有人幫忙來詢問,這個幫忙的人就是select。
IO復(fù)用模型如下所示:
多個進(jìn)程的IO注冊到一個復(fù)用器(select)上,select 會監(jiān)聽所有注冊進(jìn)來的IO。如果內(nèi)核的數(shù)據(jù)報沒有準(zhǔn)備好,調(diào)用select 的進(jìn)程將會被阻塞,而當(dāng)任一IO在內(nèi)核緩沖區(qū)中有數(shù)據(jù),select調(diào)用就會返回可讀條件,然后進(jìn)程再進(jìn)行recvform系統(tǒng)調(diào)用,內(nèi)核將數(shù)據(jù)拷貝到用戶空間,注意這個過程是阻塞的。
注意:IO 復(fù)用模型在第一個階段和第二個階段其實(shí)都有阻塞,第一個階段阻塞于 select 調(diào)用,第二個階段阻塞于數(shù)據(jù)復(fù)制。
生活場景:如果每個人都過一會就來問一下奶茶好了沒有,奶茶店的壓力也太大了。于是奶茶店想到了一個辦法,找一個中間人(select)擋在奶茶店前面,顧客(應(yīng)用進(jìn)程)詢問那個中間人奶茶好了沒有(對應(yīng)多個進(jìn)程的IO注冊到一個復(fù)用器(select)上),如果沒有好就讓顧客等待(應(yīng)用進(jìn)程阻塞于 select 調(diào)用)。中間人持續(xù)查看顧客的奶茶是否準(zhǔn)備好,如果有一個人的奶茶準(zhǔn)備好了就會去通知那個人可以取了(而當(dāng)任一IO在內(nèi)核緩沖區(qū)中有數(shù)據(jù),select調(diào)用就會返回可讀條件,然后進(jìn)程再進(jìn)行recvform系統(tǒng)調(diào)用)。
本文來源網(wǎng)絡(luò),免費(fèi)傳達(dá)知識,版權(quán)歸原作者所有。如涉及作品版權(quán)問題,請聯(lián)系我進(jìn)行刪除。
猜你喜歡:
談?wù)勄度胧杰浖募嫒菪裕?/p>
我是韋東山老師的忠實(shí)粉絲!