1. 程式人生 > >Unix下 五種 I/O模型

Unix下 五種 I/O模型

Unix下共有五種I/O模型:
  1. 阻塞式I/O 
  2. 非阻塞式I/O 
  3. I/O複用(select和poll) 
  4. 訊號驅動式I/O(SIGIO) 
  5. 非同步I/O(POSIX的aio_系列函式) 

io請求分兩步:
  1. 先將資料從儲存介質(磁碟,網路等)拷貝到核心緩衝區,此時稱為資料準備好,可以被使用者應用程式讀取。
  2. 由使用者應用程式拷貝核心緩衝區中的資料到使用者緩衝區。 

① 阻塞I/O模型            程序一直阻塞,直到資料拷貝完成

我們將函式recvfrom視為系統呼叫,不論該函式如何實現,一般都會有一個從應用程序中執行到核心中執行的切換,一段時間以後還會有一個返回到應用程序的切換。

應用程式呼叫一個IO函式,導致應用程式阻塞並等待資料準備就緒。如果資料沒有準備好,一直等待。如果資料準備好了,則從核心拷貝到使用者空間拷貝資料,IO函式返回成功指示。

程序呼叫recvfrom,此係統呼叫直到資料報到達且被複制到應用程序的緩衝區中或發生錯誤才返回,常見的錯誤如系統呼叫被訊號中斷。

程序在呼叫recvfrom開始到它返回的整段時間內是被阻塞的,該函式成功返回後,應用程序開始處理資料報。

② 非阻塞I/O模型          資料就緒之前一直輪詢

我們把一個套介面設定為非阻塞就是告訴核心,當所請求的I/O操作無法完成時,不要將程序睡眠,而是返回一個錯誤。這樣我們的I/O操作函式將不斷的測試 資料是否已經準備好,如果沒有準備好,繼續測試,直到資料準備好為止。在這個不斷測試的過程中,會大量的佔用CPU的時間。

  前三次呼叫recvfrom時仍無資料返回,因此核心立即返回一個EWOULDBLOCK錯誤。第四次呼叫recvfrom時,資料報已準備好,被拷貝到應用緩衝區,recvfrom 返回成功指示,接著就是我們處理資料。

   當一個應用程序像這樣對一個非阻塞描述字迴圈呼叫recvfrom 時,我們稱此過程為輪詢(polling)。由於應用程序像這樣連續不斷地查詢核心,看看某操作是否準備好,這對CPU時間是極大的浪費,所以這種模型只是偶爾才會遇到。

③ I/O複用模型        新增了一個系統呼叫select, 幫助程序監控多個I/O

I/O複用模型會用到select或者poll函式,這兩個函式也會使程序阻塞,但是和阻塞I/O所不同的的,這兩個函式可以同時阻塞多個I/O操作。而且可以同時對多個讀操作,多個寫操作的I/O函式進行檢測,直到有資料可讀或可寫時,才真正呼叫I/O操作函式。 

  只要有資料就緒,select呼叫返回,應用程式呼叫recvfrom將資料從核心區拷貝至使用者區。

  仔細看例項圖,發現select模型似乎有些disadvantage,即前後進行了兩次系統呼叫,比上一個模型多了一次。然而,select模型也有其明顯的優勢:每次select阻塞結束返回後,可以獲得多個準備就緒的套接字(即一個select可以對多個套接字進行管理,類似於同時監控多個套接字事件是否就緒)。

  和阻塞IO模型相比,selectI/O複用模型相當於提前阻塞了。等到有資料到來時,再呼叫recv就不會因為要等資料就緒而發生阻塞。

④ 訊號驅動I/O模型         程序通過接收到的訊號確認資料準備就緒

我們可以用訊號,讓核心在資料就緒時用訊號SIGIO通知我們,將此方法稱為訊號驅動I/O 

  首先,我們允許套接字進行訊號驅動I/O,並通過系統呼叫 sigaction 安裝一個訊號處理程式。此係統呼叫立即返回,程序繼續工作,它是非阻塞的。當資料報準備好被讀時,就為該程序生成一個SIGIO訊號。我們隨即可以在訊號處理程式中呼叫 recvfrom 來取讀資料報。

⑤ 非同步I/O    程序不受阻塞,將任務交給核心處理

我們讓核心啟動操作,並在整個操作完成後(包括將資料從核心拷貝到我們自己的緩衝區)通知我們。

呼叫aio_read函式,告訴核心描述字,緩衝區指標,緩衝區大小,檔案偏移以及通知的方式,然後立即返回。當核心將資料拷貝到緩衝區後,再通知應用程式。

對比五種 I/O模型 

前四種模型主要區別在第一階段,因為前四種模型的第二階段基本相同:在資料從記憶體拷貝到呼叫者的緩衝區時,程序阻塞於recvfrom 呼叫。然而,非同步I/O模型處理的兩個階段都不同於前四個模型。

 

同步I/O與非同步I/O

  • 同步I/O:在I/O操作未完成前,請求程序會被阻塞
  • 非同步I/O:在I/O操作未完成前,請求程序未被阻塞

上述五種I/O模型,前四種均屬於同步I/O(它們等待方式不同,搬遷動作相同),因為recvfrom呼叫均阻塞了當前請求程序。

只有最後一種io屬於非同步I/O !

  所謂同步,資料從儲存介質拷貝到核心緩衝區(資料準備的過程)完成之後,需要使用者自己將資料拷貝到使用者緩衝區。
  所謂非同步,步驟1,2 使用者都不關心,只要發起IO請求,後面得到IO結果即可。
所以,前4種IO模型都是同步的!!!

阻塞,非阻塞,同步,非同步  概括:

  • 阻塞,非阻塞:程序/執行緒要訪問的資料是否就緒,程序/執行緒是否需要等待;

  • 同步,非同步:訪問資料的方式,同步需要主動讀寫資料,在讀寫資料的過程中還是會阻塞;非同步只需要I/O操作完成的通知,並不主動讀寫資料,由作業系統核心完成資料的讀寫。

相關推薦

Unix I/O模型

Unix下共有五種I/O模型:  1. 阻塞式I/O   2. 非阻塞式I/O   3. I/O複用(select和poll)   4. 訊號驅動式I/O(SIGIO)   5. 非同步I/O(POSIX的aio_系列函式)  io請求分兩步:  1. 先將資料從儲存介質(磁碟,網路等)拷貝到核心緩衝區,此

LinuxI/O模型詳解(阻塞IO、非阻塞IO、IO複用、訊號驅動、非同步IO)

文章轉載自微信公眾號:漫話程式設計 1 什麼是I/O 程式是由資料+指令構成的,執行程式的過程可以分成下面這幾步: 1.將程式碼載入到記憶體中,逐條執行記憶體中的程式碼 2.在執行程式碼的過程中,可能需要對檔案的讀寫,即將檔案輸入(Input)

linux I/O模型

Linux下的五種I/O通訊模型 同步,非同步,阻塞,非阻塞的概念 首先,需要明確的一個問題就是,通常程式是執行在使用者態下,如果需要進行I/O操作,那麼就會發出系統呼叫(System call),由使用者態轉變為核心態,由作業系統去完成I/O操作,實際上應用程

LinuxI/O模型

  當使用socket()函式和WSASocket()函式建立套接字時,預設都是阻塞的。在建立套接字之後,通過呼叫ioctlsocket()函式,將該套接字設定為非阻塞模式。Linux下的函式是:fcntl().      套接字設定為非阻塞模式後,在呼叫Windows Sockets API函式時,呼叫函式

I/O模型的學習

來自   http://www.52im.net/thread-1935-1-1.html 4、網際網路服務端處理網路請求的原理 首先看看一個典型網際網路服務端處理網路請求的典型過程:<ignore_js_op>由上圖可以看到,主要處理步驟包括:  1)獲

Linux高手入門:LinuxI/O模型

Linux:一切皆檔案 Linux將所有外部裝置都看做檔案,對檔案的讀寫操作會呼叫核心提供的系統命令,返回一個file descriptor(fd,檔案描述符)。 Linux也把socket當成檔案,稱為socketfd(socket描述符)。 描述符是一個數字,該數字指向核心中的一個結構體(該結構

Windows SocketI/O模型筆記

Winsock 的I/O操作: 1、 兩種I/O模式  阻塞模式:執行I/O操作完成前會一直進行等待,不會將控制權交給程式。套接字 預設為阻塞模式。可以通過多執行緒技術進行處理。  非阻塞模式:執行I/O操作時,Winsock函式會返回並交出控制權。

I/O模型和Java NIO原始碼分析

  最近在學習Java網路程式設計和Netty相關的知識,瞭解到Netty是NIO模式的網路框架,但是提供了不同的Channel來支援不同模式的網路通訊處理,包括同步、非同步、阻塞和非阻塞。學習要從基礎開始,所以我們就要先了解一下相關的基礎概念和Java原生的NIO。這裡,就將最近我學習的知識總結一下,以供大

WinsockI/O模型的效能分析

非阻塞模式表現出的效能要比阻塞模式稍好,但是佔用了太多的CPU處理時間。測試伺服器將所有客戶對應的socket分類放到FD_SET集合中,然後呼叫select函式篩選出對應集合中有事件發生的socket,並對集合更新。接下來呼叫FD_ISSET巨集重新判斷一個套接字是否在原來加入的FD_SET集合中。隨著客戶

I/O模型詳解

多次系統呼叫,並馬上返回在資料拷貝的過程中,程序是阻塞的        我們把一個SOCKET介面設定為非阻塞就是告訴核心,當所請求的I/O操作無法完成時,不要將程序睡眠,而是返回一個錯誤。這樣我們的I/O操作函式將不斷的測試資料是否已經準備好,如果沒有準備好,繼續測試,直到資料準備好為止。在這個不斷測

Linux的5I/O模型(轉)

Linux下的五種I/O模型:   l         阻塞I/O   l      &nbs

詳解 Java 中 4 I/O 模型

同步、非同步、阻塞、非阻塞都是和I/O(輸入輸出)有關的概念,最簡單的檔案讀取就是I/O操作。而在檔案讀取這件事兒上,可以有多種方式。 本篇會先介紹一下I/O的基本概念,通過一個生活例子來分別解釋下這幾種I/O模型,以及Java支援的I/O模型。 基本概念 在解釋I/O模

Linux網路程式設計學習筆記(7)---5I/O模型及select輪詢

本文主要介紹5種I/O模型,select函式以及利用select實現C/S模型。 1、5種I/O模型 (1)阻塞I/O: 一直等到資料到來,才會將資料從核心中拷貝到使用者空間中。 (2)非阻塞I/O: 每過一段時

5I/O模型

 一、關於I/O模型的引出   我們都知道,為了OS的安全性等的考慮,程序是無法直接操作I/O裝置的,其必須通過系統呼叫請求核心來協助完成I/O動作,而核心會為每個I/O裝置維護一個buffer。如下圖所示:       整個請求過程為: 使用者程序發起請求,核心接受到

Java NIO學習系列I/O模型

  前面總結了很多IO、NIO相關的基礎知識點,還總結了IO和NIO之間的區別及各自適用場景,本文會從另一個視角來學習一下IO,即IO模型。什麼是IO模型?對於不同人、在不同場景下給出的答案是不同的,所以先限定一下本文的上下文:Linux環境下的network IO。   本文會從如下幾個方面展開:   

UNIX I/O 模型

開篇 RPC 中很重要的部分就是網路通訊,因此這篇敘述一下 Unix 下為解決不同 I/O 問題所設計的 I/O 模型。首先要說明的是,I/O 是個很寬泛的概念,常見的有網路 I/O、磁碟 I/O、記憶體 I/O 等。 在 Unix 系統下,不論是標準輸入還是藉助套接字接受網路輸

Java進階()Java I/O模型從BIO到NIO和Reactor模式

本文介紹了Java中的四種I/O模型,同步阻塞,同步非阻塞,多路複用,非同步阻塞。同時將NIO和BIO進行了對比,並詳細分析了基於NIO的Reactor模式,包括經典單執行緒模型以及多執行緒模式和多Reactor模式。 原創文章,轉載請務必將下面這段話置於文章開頭處(保留超連結)。 本文

網路I/O模型--5常見的網路I/O模型

  阻塞與非阻塞   阻塞就是卡在那兒什麼也不做,雙方之間也沒有資訊溝通。   非阻塞就是即使對方不能馬上完成請求,雙方之間也有資訊的溝通。 同步與非同步   同步就是一件事件只由一個過程處理完成,不論阻塞與非阻塞,最後完成這個事情的都是同一個過程   非同步就是一件事由兩個過程完成,前

linuxI/O 模型,同步/非同步,阻塞/非阻塞介紹

同步/非同步,阻塞/非阻塞 一提到網路程式設計中的 I/O 模型,總會涉及到這幾個概念,但是這幾個名詞又容易混淆,於是我想總結一下。 我們先看一下在《UNIX網路程式設計:卷一》中講到的5中 UNIX 下的 I/O 模型,分別是 阻塞式 I/O 非阻塞式

圖解UNIXI/O模型

一、簡述 UNIX系統將所有的外部裝置都看作一個檔案來看待,所有開啟的檔案都通過檔案描述符來引用。檔案描述符是一個非負整數,它指向核心中的一個結構體。當開啟一個現有檔案或建立一個新檔案時,核心向程序返回一個檔案描述符。而對於一個socket的讀寫也會有相應的檔