計(jì)算機(jī)網(wǎng)絡(luò)Socket小結(jié)

IO模型

輸入操作包括兩個(gè)階段

  • 內(nèi)核等待數(shù)據(jù)到達(dá)
  • 應(yīng)用進(jìn)程將數(shù)據(jù)從內(nèi)核拷貝數(shù)據(jù)

Unix有5種IO模型

  • 阻塞IO
  • 非阻塞IO
  • I/O復(fù)用(select/poll/epoll)
  • 信號(hào)驅(qū)動(dòng) I/O(SIGIO)
  • 異步IO

阻塞IO(BIO)

應(yīng)用進(jìn)程被阻塞數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到應(yīng)用進(jìn)程緩沖區(qū)返回蚪战。

調(diào)用阻塞IO的應(yīng)用進(jìn)程,并不影響其他進(jìn)程執(zhí)行贼急,因此這種模型的CPU利用率比較高令杈。

結(jié)合下面這張圖來深入看下阻塞IO經(jīng)歷的過程。
當(dāng)用戶進(jìn)程recvfrom這個(gè)系統(tǒng)調(diào)用時(shí)候,kernel就開始IO的第一個(gè)階段:準(zhǔn)備數(shù)據(jù)。對(duì)于network io來說,很多時(shí)候數(shù)據(jù)還沒有到達(dá)(比如沒有收到完整的UDP包,kernel要等到收到足夠的數(shù)據(jù)。而在用戶進(jìn)程這邊锭部,整個(gè)進(jìn)程都會(huì)被阻塞盆耽。當(dāng)kernel把數(shù)據(jù)準(zhǔn)備好循榆,它會(huì)將數(shù)據(jù)從kernel拷貝到用戶內(nèi)存中泽篮,然后kernal返回結(jié)果亏拉,用戶進(jìn)程解除阻塞狀態(tài)锐极。
BIO在執(zhí)行IO的兩個(gè)階段(等待數(shù)據(jù)和拷貝數(shù)據(jù))都被block了肋层。

阻塞IO

這里可以看下進(jìn)程的幾個(gè)狀態(tài)轉(zhuǎn)換,于是就和操作系統(tǒng)里面的知識(shí)聯(lián)系起來了檬嘀。
其次鸳兽,系統(tǒng)調(diào)用作為中斷的一種(soft intrrrupt) 注意read(),recvfrom() 等區(qū)別。
read()函數(shù)原型如下戚嗅,只能向已經(jīng)建立好連接的socket讀取數(shù)據(jù)

/**
 * @fd 文件描述符
 * @buf 讀出數(shù)據(jù)緩沖區(qū)
 * @count 請(qǐng)求讀出字節(jié)數(shù)
 * 成功返回讀取的字節(jié)數(shù),0表示讀到文件尾胀糜,失敗返回-1
 */
ssize_t read(int fd, void *buf, size_t count);

recvfrom()函數(shù)原型如下.如果用在已經(jīng)建立連接的socket上颅拦,需要忽略其地址和地址長(zhǎng)度參數(shù),即地址指針設(shè)置為NULL,地址長(zhǎng)度設(shè)置為0.并且flag參數(shù)設(shè)置為0,就和read()的功能一樣锥债。manual 手冊(cè)解釋的很清楚陡蝇,下面是摘錄

The only difference between recv() and read(2) is the presence of flags. With a zero flags argument, recv() is generally equivalent to read(2) (but see NOTES). Also, the following call recv(sockfd, buf, len, flags);is equivalent to recvfrom(sockfd, buf, len, flags, NULL, NULL); All three calls return the length of the message on successful completion.

/**
 * @sockfd socket文件描述符
 * @buf 讀取數(shù)據(jù)的緩沖區(qū)
 * @len 請(qǐng)求讀取數(shù)據(jù)長(zhǎng)度
 * @flags 標(biāo)志位
 * @src_addr 源地址
 * @addrlen 地址長(zhǎng)度
 * 成功返回讀取字節(jié)數(shù) 失敗返回-1
 */
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);

非阻塞IO

應(yīng)用進(jìn)程執(zhí)行系統(tǒng)調(diào)用之后,內(nèi)核返回一個(gè)錯(cuò)誤碼(errorno,全局變量)哮肚。應(yīng)用進(jìn)程可以繼續(xù)執(zhí)行登夫,但是需要不斷重復(fù)執(zhí)行系統(tǒng)調(diào)用來確定I/O 是否完成,這種方式稱為輪詢(polling)

在這種工作模式下允趟,由于應(yīng)用進(jìn)程需要不停的進(jìn)行系統(tǒng)調(diào)用恼策,加大了系統(tǒng)的開銷,導(dǎo)致CPU的利用效率不高潮剪。為什么系統(tǒng)調(diào)用開銷大涣楷?

下圖清楚的說明了非阻塞調(diào)用在第一階段不斷的詢問內(nèi)核,第二階段阻塞等待數(shù)據(jù)從內(nèi)核拷貝到進(jìn)程空間


非阻塞

IO復(fù)用

復(fù)用顧名思義就是一個(gè)應(yīng)用進(jìn)程同時(shí)監(jiān)聽多個(gè)套接字連接抗碰。

具體來看通過使用 select 或者 poll 等待數(shù)據(jù)狮斗,等待多個(gè)套接字中的任何一個(gè)變?yōu)榭勺x。這一過程會(huì)被阻塞弧蝇,當(dāng)某一個(gè)套接字可讀時(shí)返回碳褒,之后再使用 recvfrom 把數(shù)據(jù)從內(nèi)核復(fù)制到進(jìn)程中。

它可以讓單個(gè)進(jìn)程具有處理多個(gè) I/O 事件的能力看疗。又被稱為 Event Driven I/O沙峻,即事件驅(qū)動(dòng) I/O。

如果一個(gè) Web 服務(wù)器沒有 I/O 復(fù)用两芳,那么每一個(gè)客戶端發(fā)起Socket連接都需要?jiǎng)?chuàng)建一個(gè)線程去處理摔寨。如果同時(shí)有幾萬個(gè)連接,那么就需要?jiǎng)?chuàng)建相同數(shù)量的線程怖辆。相比于多進(jìn)程和多線程技術(shù)是复,I/O 復(fù)用不需要進(jìn)程線程創(chuàng)建和切換的開銷,系統(tǒng)開銷更小竖螃。

由下圖可知第一階段select()阻塞等待數(shù)據(jù)到來,第二階段recvfrom()阻塞等待數(shù)據(jù)拷貝到進(jìn)程空間緩沖區(qū)淑廊。這與阻塞IO模型的區(qū)別主要在于:阻塞IO調(diào)用recvfrom() 阻塞階段從等數(shù)據(jù)到數(shù)據(jù)拷貝到用戶緩沖區(qū),需要注意其中的區(qū)別。


IO復(fù)用

信號(hào)驅(qū)動(dòng)IO

本質(zhì)是進(jìn)程之間的通信斑鼻,在內(nèi)核接接受到數(shù)據(jù)之后通過信號(hào)來通知應(yīng)用進(jìn)程蒋纬。
可以借機(jī)復(fù)習(xí)下CSAPP里面的信號(hào)部分猎荠。

應(yīng)用進(jìn)程注冊(cè)sigalaction信號(hào),內(nèi)核立刻返回坚弱,應(yīng)用進(jìn)程在等待數(shù)據(jù)階段非阻塞蜀备。當(dāng)數(shù)據(jù)到達(dá)時(shí),內(nèi)核向應(yīng)用程序發(fā)送SIGIO信號(hào)荒叶,應(yīng)用進(jìn)程在收到該信號(hào)之后碾阁,在信號(hào)處理函數(shù)中調(diào)用recvfrom() 將數(shù)據(jù)從內(nèi)核復(fù)制到應(yīng)用進(jìn)程中。相比較非阻塞IO,信號(hào)驅(qū)動(dòng)下的CPU利用率高些楣。


信號(hào)驅(qū)動(dòng)IO

異步IO

應(yīng)用進(jìn)程執(zhí)行aio_read()系統(tǒng)調(diào)用立即返回脂凶,應(yīng)用程序在整個(gè)IO操作不會(huì)阻塞,內(nèi)核在完成所有操作之后向應(yīng)用進(jìn)程發(fā)送信號(hào)愁茁。

AIO和信號(hào)驅(qū)動(dòng)IO區(qū)別
AIO的信號(hào)通知應(yīng)用IO完成蚕钦,信號(hào)驅(qū)動(dòng)IO通知進(jìn)程開始IO.

異步IO

小結(jié)

  • 同步IO:將數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到應(yīng)用進(jìn)程緩沖區(qū),應(yīng)用進(jìn)程會(huì)阻塞
  • 異步IO:上述階段不會(huì)阻塞

下面這張圖很好總結(jié)呢五大IO模型


IO模型對(duì)比
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鹅很,一起剝皮案震驚了整個(gè)濱河市嘶居,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌促煮,老刑警劉巖邮屁,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異菠齿,居然都是意外死亡佑吝,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門绳匀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芋忿,“玉大人,你說我怎么就攤上這事襟士〉领” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵陋桂,是天一觀的道長(zhǎng)逆趣。 經(jīng)常有香客問我,道長(zhǎng)嗜历,這世上最難降的妖魔是什么宣渗? 我笑而不...
    開封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮梨州,結(jié)果婚禮上痕囱,老公的妹妹穿的比我還像新娘。我一直安慰自己暴匠,他們只是感情好鞍恢,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般帮掉。 火紅的嫁衣襯著肌膚如雪弦悉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天蟆炊,我揣著相機(jī)與錄音稽莉,去河邊找鬼。 笑死涩搓,一個(gè)胖子當(dāng)著我的面吹牛污秆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播昧甘,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼良拼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了充边?” 一聲冷哼從身側(cè)響起将饺,我...
    開封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎痛黎,沒想到半個(gè)月后予弧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡湖饱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年掖蛤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片井厌。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蚓庭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出仅仆,到底是詐尸還是另有隱情器赞,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布墓拜,位于F島的核電站港柜,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏咳榜。R本人自食惡果不足惜夏醉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望涌韩。 院中可真熱鬧畔柔,春花似錦、人聲如沸臣樱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至玄捕,卻和暖如春秸仙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背桩盲。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留席吴,地道東北人赌结。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像孝冒,于是被迫代替她去往敵國(guó)和親柬姚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容