日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(四)五种IO模型

發(fā)布時間:2024/9/5 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (四)五种IO模型 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

基本概念

我們之前編寫的套接字程序都是阻塞式的,其實這也是默認的形式?,F(xiàn)在我們需要明確一些概念:

用戶空間和內(nèi)核空間

?

首先要明確,用戶啟動的應(yīng)用程序在系統(tǒng)中以一個進程的形式存在,而無論對于網(wǎng)絡(luò)數(shù)據(jù)還是磁盤數(shù)據(jù)通常來講這個進程都無法直接訪問,必須由內(nèi)核把數(shù)據(jù)復(fù)制到用戶空間也就是進程所在的內(nèi)存空間里這個進程才可以訪問。上圖結(jié)合了網(wǎng)絡(luò)請求和磁盤數(shù)據(jù),用戶發(fā)起一個HTTP請求,請求一個HTML頁面,這個頁面就在磁盤上,其實就是把這個HTML頁面發(fā)送給用戶,用戶的瀏覽器解析HTML語言就顯示了頁面。用戶請求一個頁面其實就是阻塞的,瀏覽器必須等待所有數(shù)據(jù)返回后才能正確顯示這個頁面。所以這個請求的整個過程是阻塞的也是同步的,因為你無法讓當前這個瀏覽器標簽在等待服務(wù)器返回數(shù)據(jù)的時候去干別的。

其實對于我們之前寫的程序也是一樣,雖然服務(wù)器做的事情就是回顯客戶端發(fā)送的數(shù)據(jù),其實客戶端發(fā)送過來也是先進入服務(wù)器內(nèi)核的TCP協(xié)議棧,而你的服務(wù)端程序運行在用戶空間,內(nèi)核需要把這個數(shù)據(jù)從內(nèi)核空間復(fù)制到用戶空間,然后服務(wù)器端程序才能拿到進而進行處理然后在進行發(fā)送,發(fā)送的過程其實就是接受的反向過程。

名詞解釋

阻塞:進程發(fā)起IO調(diào)用時,如果這個IO沒有準備好數(shù)據(jù)那么進程調(diào)用的這個函數(shù)將不會返回,那么這個進程就要進入睡眠狀態(tài),也就是當前進程會被掛起。當數(shù)據(jù)拷貝到用戶空間后才返回。

非阻塞:進程發(fā)起IO調(diào)用時,被調(diào)用函數(shù)在完成IO之前不會阻塞當前進程,而是立即返回,返回的含義你可以理解為數(shù)據(jù)還沒準備好。雖然進程不阻塞,但是它需要頻繁的調(diào)用之前的函數(shù)看看數(shù)據(jù)有沒有準備好,所以這就是忙等,也叫輪訓(xùn)。

同步:進程發(fā)起一個過程調(diào)用(功能、函數(shù))調(diào)用后,在沒得到結(jié)果之前,該調(diào)用將不會返回。相當于你買麥當勞,你拿著小票在取餐處等著,如果你的餐沒有做好那么服務(wù)員是不會給你端上來的。

異步:進程發(fā)起一個過程調(diào)用,即使不能立即得到結(jié)果,但也會得到返回值。當IO完成后,內(nèi)核會通知進程資源已經(jīng)準備好了,你可以來讀取了。你可以理解為飯店點菜,點好了你可以干別的,菜好了服務(wù)員就給你端上來。

同步和阻塞、異步和非阻塞看起來概念上很像,但是他們所描述的對象不同,同步或異步是被調(diào)用者如何響應(yīng)調(diào)用者,而阻塞或非阻塞是調(diào)用者如何被處理的?;蛘邠Q句話說阻塞或非阻塞這種狀態(tài)的描述對象是進程也就調(diào)用者被如何處理的,而同步或異步的這種處理方式所描述的對象是被調(diào)用者會如何響應(yīng)調(diào)用者的。所以說的是同一個事情,但是描述的時候所站在的角度不同。

如果要把同步、異步、阻塞和非阻塞對應(yīng)到后面要說的IO模型上的話,那么阻塞和非阻塞就是進程調(diào)用的系統(tǒng)函數(shù)是否立即返回?zé)o論數(shù)據(jù)準備好沒有;同步和異步就是數(shù)據(jù)準備好后從內(nèi)核空間拷貝到用戶空間的過程中進程是否阻塞。

五種調(diào)用模型

阻塞式IO

?

阻塞式IO也是我們之前一直使用的模式其實也是默認模式。一次系統(tǒng)調(diào)用分為2個階段:

  • 數(shù)據(jù)從磁盤到內(nèi)核空間的緩沖區(qū)
  • 內(nèi)核把內(nèi)核空間的數(shù)據(jù)復(fù)制到進程空間,然后刪除內(nèi)核空間數(shù)據(jù)
  • 進程調(diào)用recvfrom就被阻塞,這時候就等數(shù)據(jù),數(shù)據(jù)準備好了就從內(nèi)核空間復(fù)制到用戶空間,復(fù)制完成之后recvfrom函數(shù)才返回,這時候進程才開始對數(shù)據(jù)進行處理。在上面的圖示數(shù)據(jù)準備好我們理解為數(shù)據(jù)可讀,結(jié)合之前的例子就是我們的服務(wù)端程序阻塞在accept處,當有新連接進來之后連接套接字變?yōu)榭勺x這時候就accept就返回了,看下圖代碼:

    另外在接收客戶端數(shù)據(jù)的時候服務(wù)端調(diào)用recv函數(shù)其實也是阻塞在這里,因為它要等著客戶端發(fā)數(shù)據(jù)來,如下圖:

    因為connFd代表一個與客戶端的連接套接字,這個套接字可讀證明有數(shù)據(jù)到達且被復(fù)制到進程的緩沖區(qū)(也就是用戶空間),這時候這個函數(shù)才返回,否則就一直阻塞。

    非阻塞式IO

    你明白了上面的阻塞式IO后再看這個非阻塞式的就很好理解,調(diào)用函數(shù)不阻塞立即返回,但是內(nèi)核不會告訴你啥時候數(shù)據(jù)到達,你的反復(fù)調(diào)用,如果第N次調(diào)用剛好數(shù)據(jù)準備好,那么就阻塞了,這時候開始等待數(shù)據(jù)復(fù)制,復(fù)制完畢函數(shù)返回。這種方式會大量消耗CPU時間。

    IO復(fù)用

    在這種模型中,這時候并不是進程直接發(fā)起資源請求的系統(tǒng)調(diào)用去請求資源,進程不會被“全程阻塞”,進程是調(diào)用select或poll函數(shù)。進程不是被阻塞在真正IO上了,而是阻塞在select或者poll上了。Select或者poll幫助用戶進程去輪詢那些IO操作是否完成。

    不過你可以看到之前都只使用一個系統(tǒng)調(diào)用,在IO復(fù)用中反而是用了兩個系統(tǒng)調(diào)用,但是使用IO復(fù)用你就可以等待多個描述符也就是通過單進程單線程實現(xiàn)并發(fā)處理,同時還可以兼顧處理套接字描述符和其他描述符。

    信號驅(qū)動模型

    讓內(nèi)核在文件描述符就緒時通過信號通知進程。從上圖可以看出這種模型進程建立信號處理程序然后立即返回,當數(shù)據(jù)準備好后發(fā)送信號通知進程,然后進程調(diào)用recvfrom系統(tǒng)調(diào)用進行復(fù)制數(shù)據(jù),當數(shù)據(jù)復(fù)制到用戶空間后函數(shù)返回(信號驅(qū)動機制需要內(nèi)核支持)。這就相當于是你點菜下單后可以繼續(xù)干其他的事情雖然菜好了會通知你,但是你需要自己去拿。但這里有個情況,如果通知進程來拿數(shù)據(jù),但是進程沒來怎么辦?這就引出了水平觸發(fā)和邊緣觸發(fā)概念

    邊緣觸發(fā)(Edge triggered):以epoll為例,當被監(jiān)控的文件描述符上有可讀寫事件時,被調(diào)用者(epoll_wait())通知進程去讀寫,如果一次沒有把全部數(shù)據(jù)讀寫完畢比如讀寫緩沖區(qū)太小,那么下次調(diào)用epoll_wait()時被調(diào)用者它不會通知進程,它只通知一次,直到該文件描述符上出現(xiàn)第二次可讀寫事件才會通知。信號驅(qū)動IO是邊緣觸發(fā)模型,epoll()支持水平也支持邊緣,默認是水平觸發(fā)。

    水平觸發(fā)(Level triggered):以epoll為例,當被監(jiān)控的文件描述符上有可讀寫事件時,被調(diào)用者(epoll_wait())通知進程去讀寫,如果一次沒有把全部數(shù)據(jù)讀寫完畢比如讀寫緩沖區(qū)太小,那么下次調(diào)用epoll_wait()時,它還會通知進程在上次沒有讀寫完的文件描述符上繼續(xù)讀寫,當然如果你一直不讀寫,它會一直通知。如果系統(tǒng)中有大量你需要讀寫的文件描述符,而且它每次都返回,這會大大降低程序檢查自己關(guān)心的文件描述符的效率,相比之下邊緣觸發(fā)效率更高。Select()和poll()都是水平觸發(fā)的。

    異步IO模型

    這種模型可以看出全程無阻塞,就等于你點菜下單后你可以續(xù)干其他的事情,菜做好了服務(wù)員會給你端上來,剩下的就是你如何處理這些菜。從效率上來講異步IO模型是最高的。

    5種IO模型比較

    從上圖可以效率從左至右逐步提高,其實IO復(fù)用也不是不阻塞,只是阻塞在像select這種IO復(fù)用函數(shù)這里。

    轉(zhuǎn)載于:https://www.cnblogs.com/rexcheny/p/9721246.html

    總結(jié)

    以上是生活随笔為你收集整理的(四)五种IO模型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。