關于IO的同步,異步,阻塞,非阻塞

上次寫了一篇文章:Unix IO 模型學習。恰巧在這次周會的時候,@fp1203 (goldendoc成員之一) 正好在講解poll和epoll的底層實現。中途正好討論了網絡IO的同步、異步、阻塞、非阻塞的概念,當時講下來,大家的理解各不相同,各執己見。搜索了網絡上的一些文章,觀點也各不相同,甚至連wiki也將異步和非阻塞當成一個概念在解釋。

    雖然網絡上充斥了大量關于同步、異步、阻塞、非阻塞的文章,但大都是抄來抄去,沒有一個權威的說法。但我找到了這一篇文章,該文章引用了《UNIX網絡編程 卷1》的介紹,這本書的作者是Richard Stevens。如果有Richard Stevens在這方面的定義或者結論,那么我想,這應該是比較有說服力的了。

    關于《UNIX網絡編程 卷1》這本書,我特意找了英文原版,也共享出來了:大家可以下載《UNIX網絡編程 卷1》的英文原版?HM格式)。

    我看了6.2這節內容,這節內容就是講IO模型的。剛剛提到的那篇文章,幾乎就是翻譯這個6.2節的。應該說,這個6.2節,對同步和異步的講解,算是很清楚的。

    下面是我自己理解的重點。

IO模型

    目前unix存在五種IO模型(這也和上一篇文章:Unix IO 模型 中提到的一致),分別是:

  1. 阻塞型 IO(blocking I/O)

  2. 非阻塞性IO(nonblocking I/O)

  3. IO多路復用(I/O multiplexing)

  4. 信號驅動IO(signal driven I/O)

  5. 異步IO(asynchronous I/O)

    IO的兩個階段

  1. 等待數據準備好

  2. 將數據從內核緩沖區復制到用戶進程緩沖區

    同步,異步的區別

        那么究竟什么是同步和異步的區別呢?請重點讀一下原文6.2節中的信號驅動IO和異步IO中的比較。最后總結出來是:

  1. 同步IO,需要用戶進程主動將存放在內核緩沖區中的數據拷貝到用戶進程中。

  2. 異步IO,內核會自動將數據從內核緩沖區拷貝到用戶緩沖區,然后再通知用戶。

        這樣,同步和異步的概念就非常明顯了。以上的五種IO模型,前面四種都是同步的,只有第五種IO模型才是異步的IO。

    阻塞和非阻塞

        那么阻塞和非阻塞呢?注意到以上五個模型。阻塞IO,非阻塞IO,只是上面的五個模型中的兩個。阻塞,非阻塞,是針對單個進程而言的。

        當對多路復用IO進行調用時,比如使用poll。需注意的是,poll是系統調用,當調用poll的時候,其實已經是陷入了內核,是內核線程在跑了。因此對于調用poll的用戶進程來講,此時是阻塞的。

        因為poll的底層實現,是去掃描每個文件描述符(fd),而如果要對感興趣的fd進行掃描,那么只能將每個描述符設置成非阻塞的形式(對
    于用戶進程來講,設置fd是阻塞還是非阻塞,可以使用系統調用fcntl),這樣才有可能進行掃描。如果掃描當中,發現有可讀(如果可讀是用戶感興趣的)
    的fd,那么select就在用戶進程層面就會返回,并且告知用戶進程哪些fd是可讀的。

        這時候,用戶進程仍然需要使用read的系統調用,將fd的數據,從內核緩沖區拷貝到用戶進程緩沖區(這也是poll為同步IO的原因)。

        那么此時的read是阻塞還是非阻塞呢?這就要看fd的狀態了,如果fd被設置成了非阻塞,那么此時的read就是非阻塞的;如果fd被設置成了阻塞,那么此時的read就是阻塞的。

        不過程序已經執行到了這時候,不管fd是阻塞還是非阻塞,都沒有任何區別,因為之前的poll,就是知道有數據準備好了才返回的,也就是說內核緩沖區已經有了數據,此時進行read,是肯定能夠將數據拷貝到用戶進程緩沖區的。

        但如果換種想法,如果poll是因為超時返回的,而我們又對一個fd(此fd是被poll輪詢過的)進行read調用,那么此時是阻塞還是非阻塞,就非常有意義了,對吧!

    結論

  1. 判斷IO是同步還是異步,是看誰主動將數據拷貝到用戶進程。

  2. select或者poll,epoll,是同步調用,進行此調用的用戶進程也處于阻塞狀態。

  3. javaScript或者nodejs中的讀取網絡(文件)數據,然后提供回調函數進行處理,是異步IO。

原文鏈接:http://blogread.cn/it/article/4108?f=wb

原創文章,作者:追馬,如若轉載,請注明出處:http://www.www58058.com/2333

(0)
追馬追馬
上一篇 2015-04-02
下一篇 2015-04-02

相關推薦

  • wordpress和discuz的負載均衡(lvs-dr)

    wordpress和discuz的負載均衡 實驗目的:利用lvs-dr模型實現wordpress和discuz的負載均衡 實驗要求:客戶端訪問wordpress或discuz服務器時,無論被調度至哪臺RS上,其會話和訪問的頁面都應保持一致; 實驗環境:一臺server用作VS,兩臺server用作RS,一臺server用于部署mysql、NFS、wordpr…

    2017-05-13
  • ls、shutdown命令使用及命令提示符格式修改

        ls、shutdown命令使用及命令提示符格式修改                      &nbs…

    Linux干貨 2016-10-17
  • 馬哥教育網絡班21期+第8周課程練習

    1、請描述網橋、集線器、二層交換機、三層交換機、路由器的功能、使用場景與區別。 集線器:工作在物理層,對信號作放大處理,轉發比特流,所有端口都是共享帶寬都是一個沖突域,使用在小型局域網內。 網橋:早期的二層數據鏈路層設備,可以建立和維護MAC地址表,獨享帶寬,每個端口是一個沖突域,使用在小型局域網內。 交換機:工作在數據鏈路層,可以學習和維護MAC地址,之后…

    Linux干貨 2016-08-05
  • Linux系統啟動流程初識

    centos系統啟動流程 本篇僅僅講解centos5和6 centos7并不適用 Linux系統的組成部分:內核+根文件系統 內核功能: 進程管理 內存管理 網絡管理 驅動程序 文件系統 安全功能 有以下目錄結構的文件系統可以被識別為根文件系統,但根文件系統本身不存在 rootfs:/bin/ /sbin /etc/ /sys/…

    Linux干貨 2016-09-11
  • 馬哥教育網絡第20期—IO類型與IO模型

    IO類型與IO模型 IO類型 同步與異步(synchronous,asynchronous):關注消息通知機制 同步:進程發出系統調用之后,不會立即有返回信息,但是一旦有返回信息,則一定是最終結果. 異步:進程發出系統調用之后,會有立即返回結果,但不是最終的結果,當內核處理完成之后,內核通過通知機制通知進程,該系統調用已完成. 阻塞與非阻塞(blocking…

    Linux干貨 2016-06-26
  • 1. 什么是Linux

        如果以前從沒有接觸過linux, 你可能會對為什么會存在這么多不同的linux發行版有些困惑. 在看linux軟件包時, 你肯定聽過發行版, LiveCD和GNU之類的等等術語, 也肯定摸不著頭腦. 第一次接觸linux,想理解會有些困難.  我們就先了解下linux系統內部結構的一些信息. &nbs…

    Linux干貨 2016-10-26
欧美性久久久久