同步io、非同步io、阻塞io、非阻塞io,這幾個詞常見於各種各樣的與網路相關的文章之中,往往不同上下文中它們的意思是不一樣的,以致於我在很長一段時間對此感到困惑,所以想寫一篇文章整理一下。
posix(可移植作業系統介面)把同步io操作定義為導致程序阻塞直到io完成的操作,反之則是非同步io
按posix的描述似乎把同步和阻塞劃等號,非同步和非阻塞劃等號,但是為什麼有的人說同步io不等於阻塞io呢?先來說說幾種常見的io模型吧。
這裡統一使用linux下的系統呼叫recv作為例子,它用於從套接字上接收乙個訊息,因為是乙個系統呼叫,所以呼叫時會從使用者程序空間切換到核心空間執行一段時間再切換回來。預設情況下recv會等到網路資料到達並且複製到使用者程序空間或者發生錯誤時返回,而第4個引數flags可以讓它馬上返回。
使用recv的預設引數一直等資料直到拷貝到使用者空間,這段時間內程序始終阻塞。a同學用杯子裝水,開啟水龍頭裝滿水然後離開。這一過程就可以看成是使用了阻塞io模型,因為如果水龍頭沒有水,他也要等到有水並裝滿杯子才能離開去做別的事情。很顯然,這種io模型是同步的。
改變flags,讓recv不管有沒有獲取到資料都返回,如果沒有資料那麼一段時間後再呼叫recv看看,如此迴圈。b同學也用杯子裝水,開啟水龍頭後發現沒有水,它離開了,過一會他又拿著杯子來看看……在中間離開的這些時間裡,b同學離開了裝水現場(回到使用者程序空間),可以做他自己的事情。這就是非阻塞io模型。但是它只有是檢查無資料的時候是非阻塞的,在資料到達的時候依然要等待複製資料到使用者空間(等著水將水杯裝滿),因此它還是同步io。
這裡在呼叫recv前先呼叫select或者poll,這2個系統呼叫都可以在核心準備好資料(網路資料到達核心)時告知使用者程序,這個時候再呼叫recv一定是有資料的。因此這一過程中它是阻塞於select或poll,而沒有阻塞於recv,有人將非阻塞io定義成在讀寫操作時沒有阻塞於系統呼叫的io操作(不包括資料從核心複製到使用者空間時的阻塞,因為這相對於網路io來說確實很短暫),如果按這樣理解,這種io模型也能稱之為非阻塞io模型,但是按posix來看,它也是同步io,那麼也和樓上一樣稱之為同步非阻塞io吧。
這種io模型比較特別,分個段。因為它能同時監聽多個檔案描述符(fd)。這個時候c同學來裝水,發現有一排水龍頭,舍管阿姨告訴他這些水龍頭都還沒有水,等有水了告訴他。於是等啊等(select呼叫中),過了一會阿姨告訴他有水了,但不知道是哪個水龍頭有水,自己看吧。於是c同學乙個個開啟,往杯子裡裝水(recv)。這裡再順便說說鼎鼎大名的epoll(高效能的代名詞啊),epoll也屬於io復用模型,主要區別在於舍管阿姨會告訴c同學哪幾個水龍頭有水了,不需要乙個個開啟看(當然還有其它區別)。
通過呼叫sigaction註冊訊號函式,等核心資料準備好的時候系統中斷當前程式,執行訊號函式(在這裡面呼叫recv)。d同學讓舍管阿姨等有水的時候通知他(註冊訊號函式),沒多久d同學得知有水了,跑去裝水。是不是很像非同步io?很遺憾,它還是同步io(省不了裝水的時間啊)。
呼叫aio_read,讓核心等資料準備好,並且複製到使用者程序空間後執行事先指定好的函式。e同學讓舍管阿姨將杯子裝滿水後通知他。整個過程e同學都可以做別的事情(沒有recv),這才是真正的非同步io。
io分兩階段:
1.資料準備階段
2.核心空間複製回使用者程序緩衝區階段
一般來講:阻塞io模型、非阻塞io模型、io復用模型(select/poll/epoll)、訊號驅動io模型都屬於同步io,因為階段2是阻塞的(儘管時間很短)。只有非同步io模型是符合posix非同步io操作含義的,不管在階段1還是階段2都可以幹別的事。 阻塞IO, 非阻塞IO, 同步IO,非同步IO介紹
一 前言 1 我們之前講了io操作什麼時候切換回來呢?我們剛剛講了 函式,這個 函式是當你的程式一遇到io操作,再一切換,這個切換的時候,切換之前你等著io操作完了再回來。2 io 為什麼不阻塞吶?因為io操作是用作業系統完成的,咋們使用者讀乙個檔案,你以為自己的程式開啟乙個檔案,然後去把檔案的內容...
IO 同步,非同步,阻塞,非阻塞
參考文章 好文推薦 唉最近真是高產似母豬,剛進新公司工作量暫時不飽和,只能每天學學學學學學查漏補缺啦,學習使我快樂哈哈哈哈哈哈哈哈 標題裡的詞彙相信都經常看到,但是能說清楚的估計20個人裡面能有1個就不錯了,網上的資料也是五花八門,大部分描述差不多,很多時候估計作者本身也是似懂非懂,我也看了很多文章...
同步 非同步 阻塞 非阻塞 I O
一 同步 非同步 首先要是多個事物,只有乙個事物,是不存在同步或非同步的。同步 指協同步調。即,多個事物不能同時進行,必須乙個乙個的來,上乙個事物結束後,下乙個事物才開始。那當乙個事物正在進行時,其他事物在幹嘛呢?嚴格來講並沒有要求,但一般都處於 等待 狀態,因為後面事物的正常進行都需要依賴前面事物...