乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      嗯,不錯(cuò)難得有人可以把IO底層原理及4種主要IO模型

       timtxu 2020-09-22

      大家知道,用戶程序進(jìn)行IO讀寫(xiě),依賴于操作系統(tǒng)底層的IO讀寫(xiě),基本上會(huì)用到底層的read&write兩大系統(tǒng)調(diào)用。

      這里涉及一個(gè)基礎(chǔ)的知識(shí):

      read系統(tǒng)調(diào)用,并不是直接從物理設(shè)備把數(shù)據(jù)讀取到內(nèi)存中,write系統(tǒng)調(diào)用,也不是把數(shù)據(jù)直接寫(xiě)入到物理設(shè)備

      上層應(yīng)用無(wú)論是調(diào)用操作系統(tǒng)的read,還是調(diào)用操作系統(tǒng)的write,都會(huì)涉及緩沖區(qū)。具體來(lái)說(shuō),調(diào)用操作系統(tǒng)的read,是把數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到進(jìn)程緩沖區(qū);而write系統(tǒng)調(diào)用,是把數(shù)據(jù)從進(jìn)程緩沖區(qū)復(fù)制到內(nèi)核緩沖區(qū)。

      上圖顯示了塊數(shù)據(jù)如何從外部源(例如硬盤(pán))移動(dòng)到正在運(yùn)行的進(jìn)程(例如RAM)內(nèi)部的存儲(chǔ)區(qū)的簡(jiǎn)化“邏輯”圖。

      首先,該進(jìn)程通過(guò)進(jìn)行read系統(tǒng)調(diào)用來(lái)填充其緩沖區(qū)。
      read讀取調(diào)用會(huì)導(dǎo)致內(nèi)核向磁盤(pán)控制器硬件發(fā)出命令以從磁盤(pán)獲取數(shù)據(jù)。
      磁盤(pán)控制器通過(guò)DMA將數(shù)據(jù)直接寫(xiě)入內(nèi)核內(nèi)存緩沖區(qū)。
      磁盤(pán)控制器完成緩沖區(qū)的填充后,內(nèi)核將數(shù)據(jù)從內(nèi)核空間中的臨時(shí)緩沖區(qū)復(fù)制到進(jìn)程指定的緩沖區(qū)中。

      緩沖區(qū)的目的,是為了減少頻繁地與設(shè)備之間的物理交換。大家都知道,外部設(shè)備的直接讀寫(xiě),涉及操作系統(tǒng)的中斷。發(fā)生系統(tǒng)中斷時(shí),需要保存之前的進(jìn)程數(shù)據(jù)和狀態(tài)等信息,而結(jié)束中斷之后,還需要恢復(fù)之前的進(jìn)程數(shù)據(jù)和狀態(tài)等信息。為了減少這種底層系統(tǒng)的時(shí)間損耗、性能損耗,于是出現(xiàn)了內(nèi)存緩沖區(qū)。

      有了內(nèi)存緩沖區(qū),上層應(yīng)用使用read系統(tǒng)調(diào)用時(shí),僅僅把數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到上層應(yīng)用的緩沖區(qū)(進(jìn)程緩沖區(qū));上層應(yīng)用使用write系統(tǒng)調(diào)用時(shí),僅僅把數(shù)據(jù)從進(jìn)程緩沖區(qū)復(fù)制到內(nèi)核緩沖區(qū)中。底層操作會(huì)對(duì)內(nèi)核緩沖區(qū)進(jìn)行監(jiān)控,等待緩沖區(qū)達(dá)到一定數(shù)量的時(shí)候,再進(jìn)行IO設(shè)備的中斷處理,集中執(zhí)行物理設(shè)備的實(shí)際IO操作,這種機(jī)制提升了系統(tǒng)的性能。至于什么時(shí)候中斷(讀中斷、寫(xiě)中斷),由操作系統(tǒng)的內(nèi)核來(lái)決定,用戶程序則不需要關(guān)心

      從數(shù)量上來(lái)說(shuō),在Linux系統(tǒng)中,操作系統(tǒng)內(nèi)核只有一個(gè)內(nèi)核緩沖區(qū)。而每個(gè)用戶程序(進(jìn)程),有自己獨(dú)立的緩沖區(qū),叫作進(jìn)程緩沖區(qū)。所以,用戶程序的IO讀寫(xiě)程序,在大多數(shù)情況下,并沒(méi)有進(jìn)行實(shí)際的IO操作,而是在進(jìn)程緩沖區(qū)和內(nèi)核緩沖區(qū)之間直接進(jìn)行數(shù)據(jù)的交換

      文件句柄,也叫文件描述符。在Linux系統(tǒng)中,文件可分為:普通文件、目錄文件、鏈接文件和設(shè)備文件。文件描述符(File Descriptor)是內(nèi)核為了高效管理已被打開(kāi)的文件所創(chuàng)建的索引,它是一個(gè)非負(fù)整數(shù)(通常是小整數(shù)),用于指代被打開(kāi)的文件。所有的IO系統(tǒng)調(diào)用,包括socket的讀寫(xiě)調(diào)用,都是通過(guò)文件描述符完成的。

      4種主要的IO模型

      介紹4種IO模型之前要先介紹兩組概念

      阻塞與非阻塞

      阻塞IO,指的是需要內(nèi)核IO操作徹底完成后,才返回到用戶空間執(zhí)行用戶的操作。阻塞指的是用戶空間程序的執(zhí)行狀態(tài)。傳統(tǒng)的IO模型都是同步阻塞IO。在Java中,默認(rèn)創(chuàng)建的socket都是阻塞的

      同步與異步

      同步IO,是一種用戶空間與內(nèi)核空間的IO發(fā)起方式。同步IO是指用戶空間的線程是主動(dòng)發(fā)起IO請(qǐng)求的一方,內(nèi)核空間是被動(dòng)接受方。異步IO則反過(guò)來(lái),是指系統(tǒng)內(nèi)核是主動(dòng)發(fā)起IO請(qǐng)求的一方,用戶空間的線程是被動(dòng)接受方

      在Java應(yīng)用程序進(jìn)程中,默認(rèn)情況下,所有的socket連接的IO操作都是同步阻塞IO(Blocking IO)。

      在阻塞式IO模型中,Java應(yīng)用程序從IO系統(tǒng)調(diào)用開(kāi)始,直到系統(tǒng)調(diào)用返回,在這段時(shí)間內(nèi),Java進(jìn)程是阻塞的。返回成功后,應(yīng)用進(jìn)程開(kāi)始處理用戶空間的緩存區(qū)數(shù)據(jù)。

      從Java啟動(dòng)IO讀的read系統(tǒng)調(diào)用開(kāi)始,用戶線程就進(jìn)入阻塞狀態(tài)。
      當(dāng)系統(tǒng)內(nèi)核收到read系統(tǒng)調(diào)用,就開(kāi)始準(zhǔn)備數(shù)據(jù)。一開(kāi)始,數(shù)據(jù)可能還沒(méi)有到達(dá)內(nèi)核緩沖區(qū)(例如,還沒(méi)有收到一個(gè)完整的socket數(shù)據(jù)包),這個(gè)時(shí)候內(nèi)核就要等待。
      內(nèi)核一直等到完整的數(shù)據(jù)到達(dá),就會(huì)將數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到用戶緩沖區(qū)(用戶空間的內(nèi)存),然后內(nèi)核返回結(jié)果(例如返回復(fù)制到用戶緩沖區(qū)中的字節(jié)數(shù))。
      直到內(nèi)核返回后,用戶線程才會(huì)解除阻塞的狀態(tài),重新運(yùn)行起來(lái)。

      阻塞IO的優(yōu)點(diǎn)是:

      應(yīng)用的程序開(kāi)發(fā)非常簡(jiǎn)單;在阻塞等待數(shù)據(jù)期間,用戶線程掛起。在阻塞期間,用戶線程基本不會(huì)占用CPU資源。

      阻塞IO的缺點(diǎn)是:

      一般情況下,會(huì)為每個(gè)連接配備一個(gè)獨(dú)立的線程;反過(guò)來(lái)說(shuō),就是一個(gè)線程維護(hù)一個(gè)連接的IO操作。在并發(fā)量小的情況下,這樣做沒(méi)有什么問(wèn)題。但是,當(dāng)在高并發(fā)的應(yīng)用場(chǎng)景下,需要大量的線程來(lái)維護(hù)大量的網(wǎng)絡(luò)連接,內(nèi)存、線程切換開(kāi)銷(xiāo)會(huì)非常巨大。因此,基本上阻塞IO模型在高并發(fā)應(yīng)用場(chǎng)景下是不可用的。

      在內(nèi)核數(shù)據(jù)沒(méi)有準(zhǔn)備好的階段,用戶線程發(fā)起IO請(qǐng)求時(shí),立即返回。所以,為了讀取到最終的數(shù)據(jù),用戶線程需要不斷地發(fā)起IO系統(tǒng)調(diào)用。
      內(nèi)核數(shù)據(jù)到達(dá)后,用戶線程發(fā)起系統(tǒng)調(diào)用,用戶線程阻塞。內(nèi)核開(kāi)始復(fù)制數(shù)據(jù),它會(huì)將數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到用戶緩沖區(qū)(用戶空間的內(nèi)存),然后內(nèi)核返回結(jié)果(例如返回復(fù)制到的用戶緩沖區(qū)的字節(jié)數(shù))。
      用戶線程讀到數(shù)據(jù)后,才會(huì)解除阻塞狀態(tài),重新運(yùn)行起來(lái)。也就是說(shuō),用戶進(jìn)程需要經(jīng)過(guò)多次的嘗試,才能保證最終真正讀到數(shù)據(jù),而后繼續(xù)執(zhí)行。

      同步非阻塞IO的特點(diǎn):

      應(yīng)用程序的線程需要不斷地進(jìn)行IO系統(tǒng)調(diào)用,輪詢數(shù)據(jù)是否已經(jīng)準(zhǔn)備好,如果沒(méi)有準(zhǔn)備好,就繼續(xù)輪詢,直到完成IO系統(tǒng)調(diào)用為止。

      同步非阻塞IO的優(yōu)點(diǎn):

      每次發(fā)起的IO系統(tǒng)調(diào)用,在內(nèi)核等待數(shù)據(jù)過(guò)程中可以立即返回。用戶線程不會(huì)阻塞,實(shí)時(shí)性較好。

      同步非阻塞IO的缺點(diǎn):

      不斷地輪詢內(nèi)核,這將占用大量的CPU時(shí)間,效率低下

      總體來(lái)說(shuō),在高并發(fā)應(yīng)用場(chǎng)景下,同步非阻塞IO也是不可用的。一般Web服務(wù)器不使用這種IO模型。這種IO模型一般很少直接使用,而是在其他IO模型中使用非阻塞IO這一特性。在Java的實(shí)際開(kāi)發(fā)中,也不會(huì)涉及這種IO模型

      如何避免同步非阻塞IO模型中輪詢等待的問(wèn)題呢?這就是IO多路復(fù)用模型

      在IO多路復(fù)用模型中,引入了一種新的系統(tǒng)調(diào)用,查詢IO的就緒狀態(tài)。在Linux系統(tǒng)中,對(duì)應(yīng)的系統(tǒng)調(diào)用為select/epoll系統(tǒng)調(diào)用。通過(guò)該系統(tǒng)調(diào)用,一個(gè)進(jìn)程可以監(jiān)視多個(gè)文件描述符,一旦某個(gè)描述符就緒(一般是內(nèi)核緩沖區(qū)可讀/可寫(xiě)),內(nèi)核能夠?qū)⒕途w的狀態(tài)返回給應(yīng)用程序。隨后,應(yīng)用程序根據(jù)就緒的狀態(tài),進(jìn)行相應(yīng)的IO系統(tǒng)調(diào)用。

      目前支持IO多路復(fù)用的系統(tǒng)調(diào)用,有select、epoll等等。select系統(tǒng)調(diào)用,幾乎在所有的操作系統(tǒng)上都有支持,具有良好的跨平臺(tái)特性。epoll是在Linux 2.6內(nèi)核中提出的,是select系統(tǒng)調(diào)用的Linux增強(qiáng)版本。

      在IO多路復(fù)用模型中通過(guò)select/epoll系統(tǒng)調(diào)用,單個(gè)應(yīng)用程序的線程,可以不斷地輪詢成百上千的socket連接,當(dāng)某個(gè)或者某些socket網(wǎng)絡(luò)連接有IO就緒的狀態(tài),就返回對(duì)應(yīng)的可以執(zhí)行的讀寫(xiě)操作

      舉個(gè)例子來(lái)說(shuō)明IO多路復(fù)用模型的流程。發(fā)起一個(gè)多路復(fù)用IO的read讀操作的系統(tǒng)調(diào)用,流程如下:

      選擇器注冊(cè)。在這種模式中,首先,將需要read操作的目標(biāo)socket網(wǎng)絡(luò)連接,提前注冊(cè)到select/epoll選擇器中,Java中對(duì)應(yīng)的選擇器類(lèi)是Selector類(lèi)。然后,才可以開(kāi)啟整個(gè)IO多路復(fù)用模型的輪詢流程。
      就緒狀態(tài)的輪詢。通過(guò)選擇器的查詢方法,查詢注冊(cè)過(guò)的所有socket連接的就緒狀態(tài)。通過(guò)查詢的系統(tǒng)調(diào)用,內(nèi)核會(huì)返回一個(gè)就緒的socket列表。當(dāng)任何一個(gè)注冊(cè)過(guò)的socket中的數(shù)據(jù)準(zhǔn)備好了,內(nèi)核緩沖區(qū)有數(shù)據(jù)(就緒)了,內(nèi)核就將該socket加入到就緒的列表中。 當(dāng)用戶進(jìn)程調(diào)用了select查詢方法,那么整個(gè)線程會(huì)被阻塞掉。
      用戶線程獲得了就緒狀態(tài)的列表后,根據(jù)其中的socket連接,發(fā)起read系統(tǒng)調(diào)用,用戶線程阻塞。內(nèi)核開(kāi)始復(fù)制數(shù)據(jù),將數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到用戶緩沖區(qū)。
      復(fù)制完成后,內(nèi)核返回結(jié)果,用戶線程才會(huì)解除阻塞的狀態(tài),用戶線程讀取到了數(shù)據(jù),繼續(xù)執(zhí)行。

      IO多路復(fù)用模型的特點(diǎn)

      涉及兩種系統(tǒng)調(diào)用(System Call),
      一種是select/epoll(就緒查詢)
      一種是IO操作。
      和NIO模型相似,多路復(fù)用IO也需要輪詢。負(fù)責(zé)select/epoll狀態(tài)查詢調(diào)用的線程,需要不斷地進(jìn)行select/epoll輪詢,查找出達(dá)到IO操作就緒的socket連接。

      IO多路復(fù)用模型的優(yōu)點(diǎn)

      與一個(gè)線程維護(hù)一個(gè)連接的阻塞IO模式相比,使用select/epoll的最大優(yōu)勢(shì)在于,一個(gè)選擇器查詢線程可以同時(shí)處理成千上萬(wàn)個(gè)連接(Connection)。系統(tǒng)不必創(chuàng)建大量的線程,也不必維護(hù)這些線程,從而大大減小了系統(tǒng)的開(kāi)銷(xiāo)。

      IO多路復(fù)用模型的缺點(diǎn)

      本質(zhì)上,select/epoll系統(tǒng)調(diào)用是阻塞式的,屬于同步IO。都需要在讀寫(xiě)事件就緒后,由系統(tǒng)調(diào)用本身負(fù)責(zé)進(jìn)行讀寫(xiě),也就是說(shuō)這個(gè)讀寫(xiě)過(guò)程是阻塞的

      如果要徹底地解除線程的阻塞,就必須使用異步IO模型

      異步IO模型(Asynchronous IO,簡(jiǎn)稱為AIO)。AIO的基本流程是:用戶線程通過(guò)系統(tǒng)調(diào)用,向內(nèi)核注冊(cè)某個(gè)IO操作。內(nèi)核在整個(gè)IO操作(包括數(shù)據(jù)準(zhǔn)備、數(shù)據(jù)復(fù)制)完成后,通知用戶程序,用戶執(zhí)行后續(xù)的業(yè)務(wù)操作。

      舉個(gè)例子。發(fā)起一個(gè)異步IO的read讀操作的系統(tǒng)調(diào)用,流程如下:

      當(dāng)用戶線程發(fā)起了read系統(tǒng)調(diào)用,立刻就可以開(kāi)始去做其他的事,用戶線程不阻塞。
      內(nèi)核就開(kāi)始了IO的第一個(gè)階段:準(zhǔn)備數(shù)據(jù)。等到數(shù)據(jù)準(zhǔn)備好了,內(nèi)核就會(huì)將數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到用戶緩沖區(qū)(用戶空間的內(nèi)存)。
      內(nèi)核會(huì)給用戶線程發(fā)送一個(gè)信號(hào)(Signal),或者回調(diào)用戶線程注冊(cè)的回調(diào)接口,告訴用戶線程read操作完成了。
      用戶線程讀取用戶緩沖區(qū)的數(shù)據(jù),完成后續(xù)的業(yè)務(wù)操作。

      異步IO模型的特點(diǎn)

      在內(nèi)核等待數(shù)據(jù)和復(fù)制數(shù)據(jù)的兩個(gè)階段,用戶線程都不是阻塞的。用戶線程需要接收內(nèi)核的IO操作完成的事件,或者用戶線程需要注冊(cè)一個(gè)IO操作完成的回調(diào)函數(shù)。正因?yàn)槿绱?,異步IO有的時(shí)候也被稱為信號(hào)驅(qū)動(dòng)IO

      異步IO異步模型的缺點(diǎn)

      應(yīng)用程序僅需要進(jìn)行事件的注冊(cè)與接收,其余的工作都留給了操作系統(tǒng),也就是說(shuō),需要底層內(nèi)核提供支持。 理論上來(lái)說(shuō),異步IO是真正的異步輸入輸出,它的吞吐量高于IO多路復(fù)用模型的吞吐量

      就目前而言,Windows系統(tǒng)下通過(guò)IOCP實(shí)現(xiàn)了真正的異步IO。而在Linux系統(tǒng)下,異步IO模型在2.6版本才引入,目前并不完善,其底層實(shí)現(xiàn)仍使用epoll,與IO多路復(fù)用相同,因此在性能上沒(méi)有明顯的優(yōu)勢(shì)。 大多數(shù)的高并發(fā)服務(wù)器端的程序,一般都是基于Linux系統(tǒng)的。因而,目前這類(lèi)高并發(fā)網(wǎng)絡(luò)應(yīng)用程序的開(kāi)發(fā),大多采用IO多路復(fù)用模型

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類(lèi)似文章 更多