摘要:缺點(diǎn)每個(gè)連接需要獨(dú)立的進(jìn)程線(xiàn)程多帶帶處理,當(dāng)并發(fā)請(qǐng)求量大時(shí)為了維護(hù)程序,內(nèi)存線(xiàn)程切換開(kāi)銷(xiāo)較大,這種模型在實(shí)際生產(chǎn)中很少使用。而在系統(tǒng)下,才引入,目前并不完善,因此在下實(shí)現(xiàn)高并發(fā)網(wǎng)絡(luò)編程時(shí)都是以復(fù)用模型模式為主。
思維導(dǎo)圖 互聯(lián)網(wǎng)服務(wù)端處理網(wǎng)絡(luò)請(qǐng)求的原理
首先看看一個(gè)典型互聯(lián)網(wǎng)服務(wù)端處理網(wǎng)絡(luò)請(qǐng)求的典型過(guò)程:
由上圖可以看到,主要處理步驟包括:
獲取請(qǐng)求數(shù)據(jù),客戶(hù)端與服務(wù)器建立連接發(fā)出請(qǐng)求,服務(wù)器接受請(qǐng)求(1-3);
構(gòu)建響應(yīng),當(dāng)服務(wù)器接收完請(qǐng)求,并在用戶(hù)空間處理客戶(hù)端的請(qǐng)求,直到構(gòu)建響應(yīng)完成(4);
返回?cái)?shù)據(jù),服務(wù)器將已構(gòu)建好的響應(yīng)再通過(guò)內(nèi)核空間的網(wǎng)絡(luò) I/O 發(fā)還給客戶(hù)端(5-7)。
設(shè)計(jì)服務(wù)端并發(fā)模型時(shí),主要有如下兩個(gè)關(guān)鍵點(diǎn):
服務(wù)器如何管理連接,獲取輸入數(shù)據(jù);
服務(wù)器如何處理請(qǐng)求。
以上兩個(gè)關(guān)鍵點(diǎn)最終都與操作系統(tǒng)的 I/O 模型以及線(xiàn)程(進(jìn)程)模型相關(guān)。下面先詳細(xì)介紹這I/O模型。
I/O 模型的基本認(rèn)識(shí)介紹操作系統(tǒng)的 I/O 模型之前,先了解一下幾個(gè)概念:
阻塞調(diào)用與非阻塞調(diào)用;
阻塞調(diào)用是指調(diào)用結(jié)果返回之前,當(dāng)前線(xiàn)程會(huì)被掛起,調(diào)用線(xiàn)程只有在得到結(jié)果之后才會(huì)返回;
非阻塞調(diào)用指在不能立刻得到結(jié)果之前,該調(diào)用不會(huì)阻塞當(dāng)前線(xiàn)程。
兩者的最大區(qū)別在于被調(diào)用方在收到請(qǐng)求到返回結(jié)果之前的這段時(shí)間內(nèi),調(diào)用方是否一直在等待。
阻塞是指調(diào)用方一直在等待而且別的事情什么都不做;非阻塞是指調(diào)用方先去忙別的事情。
同步處理與異步處理:同步處理是指被調(diào)用方得到最終結(jié)果之后才返回給調(diào)用方;異步處理是指被調(diào)用方先返回應(yīng)答,然后再計(jì)算調(diào)用結(jié)果,計(jì)算完最終結(jié)果后再通知并返回給調(diào)用方。
阻塞、非阻塞和同步、異步的區(qū)別(阻塞、非阻塞和同步、異步其實(shí)針對(duì)的對(duì)象是不一樣的):
阻塞、非阻塞的討論對(duì)象是調(diào)用者;
同步、異步的討論對(duì)象是被調(diào)用者。
recvfrom 函數(shù):
recvfrom 函數(shù)(經(jīng) Socket 接收數(shù)據(jù)),這里把它視為系統(tǒng)調(diào)用。
一個(gè)輸入操作通常包括兩個(gè)不同的階段:
等待數(shù)據(jù)準(zhǔn)備好;
從內(nèi)核向進(jìn)程復(fù)制數(shù)據(jù)。
對(duì)于一個(gè)套接字上的輸入操作:
第一步通常涉及等待數(shù)據(jù)從網(wǎng)絡(luò)中到達(dá)。當(dāng)所等待分組到達(dá)時(shí),它被復(fù)制到內(nèi)核中的某個(gè)緩沖區(qū)。
第二步就是把數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到應(yīng)用進(jìn)程緩沖區(qū)。
實(shí)際應(yīng)用程序在系統(tǒng)調(diào)用完成上面的 2 步操作時(shí),調(diào)用方式的阻塞、非阻塞,操作系統(tǒng)在處理應(yīng)用程序請(qǐng)求時(shí),處理方式的同步、異步處理的不同,可以分為 5 種 I/O 模型。
I/O模型 I/O模型1:阻塞式 I/O 模型(blocking I/O)在阻塞式 I/O 模型中,應(yīng)用程序在從調(diào)用 recvfrom 開(kāi)始到它返回有數(shù)據(jù)報(bào)準(zhǔn)備好這段時(shí)間是阻塞的,recvfrom 返回成功后,應(yīng)用進(jìn)程開(kāi)始處理數(shù)據(jù)報(bào)。
比喻:一個(gè)人在釣魚(yú),當(dāng)沒(méi)魚(yú)上鉤時(shí),就坐在岸邊一直等。I/O模型2:非阻塞式 I/O 模型(non-blocking I/O)優(yōu)點(diǎn):程序簡(jiǎn)單,在阻塞等待數(shù)據(jù)期間進(jìn)程/線(xiàn)程掛起,基本不會(huì)占用 CPU 資源。
缺點(diǎn):每個(gè)連接需要獨(dú)立的進(jìn)程/線(xiàn)程多帶帶處理,當(dāng)并發(fā)請(qǐng)求量大時(shí)為了維護(hù)程序,內(nèi)存、線(xiàn)程切換開(kāi)銷(xiāo)較大,這種模型在實(shí)際生產(chǎn)中很少使用。
在非阻塞式 I/O 模型中,應(yīng)用程序把一個(gè)套接口設(shè)置為非阻塞,就是告訴內(nèi)核,當(dāng)所請(qǐng)求的 I/O 操作無(wú)法完成時(shí),不要將進(jìn)程睡眠。
而是返回一個(gè)錯(cuò)誤,應(yīng)用程序基于 I/O 操作函數(shù)將不斷的輪詢(xún)數(shù)據(jù)是否已經(jīng)準(zhǔn)備好,如果沒(méi)有準(zhǔn)備好,繼續(xù)輪詢(xún),直到數(shù)據(jù)準(zhǔn)備好為止。
比喻:邊釣魚(yú)邊玩手機(jī),隔會(huì)再看看有沒(méi)有魚(yú)上鉤,有的話(huà)就迅速拉桿。I/O模型3:I/O 復(fù)用模型(I/O multiplexing)優(yōu)點(diǎn):不會(huì)阻塞在內(nèi)核的等待數(shù)據(jù)過(guò)程,每次發(fā)起的 I/O 請(qǐng)求可以立即返回,不用阻塞等待,實(shí)時(shí)性較好
缺點(diǎn):輪詢(xún)將會(huì)不斷地詢(xún)問(wèn)內(nèi)核,這將占用大量的 CPU 時(shí)間,系統(tǒng)資源利用率較低,所以一般 Web 服務(wù)器不使用這種 I/O 模型。
在 I/O 復(fù)用模型中,會(huì)用到 Select 或 Poll 函數(shù)或 Epoll 函數(shù)(Linux 2.6 以后的內(nèi)核開(kāi)始支持),這兩個(gè)函數(shù)也會(huì)使進(jìn)程阻塞,但是和阻塞 I/O 有所不同。
這兩個(gè)函數(shù)可以同時(shí)阻塞多個(gè) I/O 操作,而且可以同時(shí)對(duì)多個(gè)讀操作,多個(gè)寫(xiě)操作的 I/O 函數(shù)進(jìn)行檢測(cè),直到有數(shù)據(jù)可讀或可寫(xiě)時(shí),才真正調(diào)用 I/O 操作函數(shù)。
比喻:放了一堆魚(yú)竿,在岸邊一直守著這堆魚(yú)竿,沒(méi)魚(yú)上鉤就玩手機(jī)。優(yōu)點(diǎn):可以基于一個(gè)阻塞對(duì)象,同時(shí)在多個(gè)描述符上等待就緒,而不是使用多個(gè)線(xiàn)程(每個(gè)文件描述符一個(gè)線(xiàn)程),這樣可以大大節(jié)省系統(tǒng)資源。
缺點(diǎn):當(dāng)連接數(shù)較少時(shí)效率相比多線(xiàn)程+阻塞 I/O 模型效率較低,可能延遲更大,因?yàn)閱蝹€(gè)連接處理需要 2 次系統(tǒng)調(diào)用,占用時(shí)間會(huì)有增加。
眾所周之,Nginx這樣的高性能互聯(lián)網(wǎng)反向代理服務(wù)器大獲成功的關(guān)鍵就是得益于Epoll。
I/O模型4:信號(hào)驅(qū)動(dòng)式 I/O 模型(signal-driven I/O)在信號(hào)驅(qū)動(dòng)式 I/O 模型中,應(yīng)用程序使用套接口進(jìn)行信號(hào)驅(qū)動(dòng) I/O,并安裝一個(gè)信號(hào)處理函數(shù),進(jìn)程繼續(xù)運(yùn)行并不阻塞。
當(dāng)數(shù)據(jù)準(zhǔn)備好時(shí),進(jìn)程會(huì)收到一個(gè) SIGIO 信號(hào),可以在信號(hào)處理函數(shù)中調(diào)用 I/O 操作函數(shù)處理數(shù)據(jù)。
比喻:魚(yú)竿上系了個(gè)鈴鐺,當(dāng)鈴鐺響,就知道魚(yú)上鉤,然后可以專(zhuān)心玩手機(jī)。優(yōu)點(diǎn):線(xiàn)程并沒(méi)有在等待數(shù)據(jù)時(shí)被阻塞,可以提高資源的利用率。
缺點(diǎn):信號(hào) I/O 在大量 IO 操作時(shí)可能會(huì)因?yàn)樾盘?hào)隊(duì)列溢出導(dǎo)致沒(méi)法通知。
信號(hào)驅(qū)動(dòng) I/O 盡管對(duì)于處理 UDP 套接字來(lái)說(shuō)有用,即這種信號(hào)通知意味著到達(dá)一個(gè)數(shù)據(jù)報(bào),或者返回一個(gè)異步錯(cuò)誤。
但是,對(duì)于 TCP 而言,信號(hào)驅(qū)動(dòng)的 I/O 方式近乎無(wú)用,因?yàn)閷?dǎo)致這種通知的條件為數(shù)眾多,每一個(gè)來(lái)進(jìn)行判別會(huì)消耗很大資源,與前幾種方式相比優(yōu)勢(shì)盡失。
I/O模型5:異步 I/O 模型(即AIO,全稱(chēng)asynchronous I/O)由 POSIX 規(guī)范定義,應(yīng)用程序告知內(nèi)核啟動(dòng)某個(gè)操作,并讓內(nèi)核在整個(gè)操作(包括將數(shù)據(jù)從內(nèi)核拷貝到應(yīng)用程序的緩沖區(qū))完成后通知應(yīng)用程序。
這種模型與信號(hào)驅(qū)動(dòng)模型的主要區(qū)別在于:信號(hào)驅(qū)動(dòng) I/O 是由內(nèi)核通知應(yīng)用程序何時(shí)啟動(dòng)一個(gè) I/O 操作,而異步 I/O 模型是由內(nèi)核通知應(yīng)用程序 I/O 操作何時(shí)完成。
優(yōu)點(diǎn):異步 I/O 能夠充分利用 DMA 特性,讓 I/O 操作與計(jì)算重疊。缺點(diǎn):要實(shí)現(xiàn)真正的異步 I/O,操作系統(tǒng)需要做大量的工作。目前 Windows 下通過(guò) IOCP 實(shí)現(xiàn)了真正的異步 I/O。
而在 Linux 系統(tǒng)下,Linux 2.6才引入,目前 AIO 并不完善,因此在 Linux 下實(shí)現(xiàn)高并發(fā)網(wǎng)絡(luò)編程時(shí)都是以 IO 復(fù)用模型模式為主。
關(guān)于AOI的介紹,請(qǐng)見(jiàn)
5 種 I/O 模型總結(jié)從上圖中我們可以看出,越往后,阻塞越少,理論上效率也是最優(yōu)。
這五種 I/O 模型中,前四種屬于同步 I/O,因?yàn)槠渲姓嬲?I/O 操作(recvfrom)將阻塞進(jìn)程/線(xiàn)程,只有異步 I/O 模型才與 POSIX 定義的異步 I/O 相匹配。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/72524.html
摘要:如需了解更多物聯(lián)網(wǎng)網(wǎng)絡(luò)編程知識(shí)請(qǐng)點(diǎn)擊物聯(lián)網(wǎng)云端開(kāi)發(fā)武器庫(kù)物聯(lián)網(wǎng)高并發(fā)編程之網(wǎng)絡(luò)編程中的線(xiàn)程模型值得說(shuō)明的是,具體選擇線(xiàn)程還是進(jìn)程,更多是與平臺(tái)及編程語(yǔ)言相關(guān)。 如需了解更多物聯(lián)網(wǎng)網(wǎng)絡(luò)編程知識(shí)請(qǐng)點(diǎn)擊:物聯(lián)網(wǎng)云端開(kāi)發(fā)武器庫(kù) 物聯(lián)網(wǎng)高并發(fā)編程之網(wǎng)絡(luò)編程中的線(xiàn)程模型 值得說(shuō)明的是,具體選擇線(xiàn)程還是進(jìn)程,更多是與平臺(tái)及編程語(yǔ)言相關(guān)。例如 C 語(yǔ)言使用線(xiàn)程和進(jìn)程都可以(例如 Nginx 使用進(jìn)程...
摘要:?jiǎn)栴}任一文件句柄的不成功會(huì)阻塞住整個(gè)應(yīng)用。主要解決的前兩個(gè)問(wèn)題通過(guò)一個(gè)數(shù)組向內(nèi)核傳遞需要關(guān)注的事件消除文件句柄上限,同時(shí)使用不同字段分別標(biāo)注關(guān)注事件和發(fā)生事件,來(lái)避免重復(fù)初始化。問(wèn)題逐個(gè)排查所有文件句柄狀態(tài)效率不高。 C10K問(wèn)題思維導(dǎo)圖 showImg(https://segmentfault.com/img/bVbkrKe?w=1818&h=1276); C10K問(wèn)題出現(xiàn)前期 大家...
摘要:表示的是兩個(gè),當(dāng)其中任意一個(gè)計(jì)算完并發(fā)編程之是線(xiàn)程安全并且高效的,在并發(fā)編程中經(jīng)??梢?jiàn)它的使用,在開(kāi)始分析它的高并發(fā)實(shí)現(xiàn)機(jī)制前,先講講廢話(huà),看看它是如何被引入的。電商秒殺和搶購(gòu),是兩個(gè)比較典型的互聯(lián)網(wǎng)高并發(fā)場(chǎng)景。 干貨:深度剖析分布式搜索引擎設(shè)計(jì) 分布式,高可用,和機(jī)器學(xué)習(xí)一樣,最近幾年被提及得最多的名詞,聽(tīng)名字多牛逼,來(lái),我們一步一步來(lái)?yè)羝魄皟蓚€(gè)名詞,今天我們首先來(lái)說(shuō)說(shuō)分布式。 探究...
摘要:表示的是兩個(gè),當(dāng)其中任意一個(gè)計(jì)算完并發(fā)編程之是線(xiàn)程安全并且高效的,在并發(fā)編程中經(jīng)??梢?jiàn)它的使用,在開(kāi)始分析它的高并發(fā)實(shí)現(xiàn)機(jī)制前,先講講廢話(huà),看看它是如何被引入的。電商秒殺和搶購(gòu),是兩個(gè)比較典型的互聯(lián)網(wǎng)高并發(fā)場(chǎng)景。 干貨:深度剖析分布式搜索引擎設(shè)計(jì) 分布式,高可用,和機(jī)器學(xué)習(xí)一樣,最近幾年被提及得最多的名詞,聽(tīng)名字多牛逼,來(lái),我們一步一步來(lái)?yè)羝魄皟蓚€(gè)名詞,今天我們首先來(lái)說(shuō)說(shuō)分布式。 探究...
摘要:表示的是兩個(gè),當(dāng)其中任意一個(gè)計(jì)算完并發(fā)編程之是線(xiàn)程安全并且高效的,在并發(fā)編程中經(jīng)常可見(jiàn)它的使用,在開(kāi)始分析它的高并發(fā)實(shí)現(xiàn)機(jī)制前,先講講廢話(huà),看看它是如何被引入的。電商秒殺和搶購(gòu),是兩個(gè)比較典型的互聯(lián)網(wǎng)高并發(fā)場(chǎng)景。 干貨:深度剖析分布式搜索引擎設(shè)計(jì) 分布式,高可用,和機(jī)器學(xué)習(xí)一樣,最近幾年被提及得最多的名詞,聽(tīng)名字多牛逼,來(lái),我們一步一步來(lái)?yè)羝魄皟蓚€(gè)名詞,今天我們首先來(lái)說(shuō)說(shuō)分布式。 探究...
閱讀 3951·2021-07-28 18:10
閱讀 2643·2019-08-30 15:44
閱讀 1162·2019-08-30 14:07
閱讀 3516·2019-08-29 17:20
閱讀 1642·2019-08-26 18:35
閱讀 3596·2019-08-26 13:42
閱讀 1870·2019-08-26 11:58
閱讀 1663·2019-08-23 18:33