關於IO的同步,非同步,阻塞,非阻塞

2021-07-04 10:18:05 字數 1664 閱讀 7551

關於網路io的同步、非同步、阻塞、非阻塞的文章網上有很多,搜尋了對比了一下,觀點也各不相同,即使是wiki也把非同步和非阻塞區分得不是很清楚。下面我就結合《unix網路程式設計 卷1》中的介紹,來說一說自己的理解。

io模型

首先我們要先知道目前unix存在的五種io模型,分別是:

io的兩個階段

1.等待資料準備好

2.將資料從核心緩衝區複製到使用者程序緩衝區

同步,非同步的區別

那麼究竟什麼是同步和非同步的區別呢?我的總結如下:

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

阻塞和非阻塞

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

我們先從阻塞和非阻塞socket來簡單理解一下二者的區別:通常的,對乙個檔案描述符指定的檔案或裝置, 有兩種工作方式: 阻塞與非阻塞方式。

(1). 阻塞方式是指: 當試圖對該檔案描述符進行讀寫時,如果當時沒有資料可讀,或者暫時不可寫,程式就進入等待狀態,直到有東西可讀或者可寫為止。

(2). 非阻塞方式是指: 如果沒有資料可讀,或者不可寫,讀寫函式馬上返回,而不會等待。

(3). 舉個例子來說,比如說小明去找乙個女神聊天,女神卻不在。 如果小明捨不得走,只能在女神大門口死等著,當然小明可以休息。當女神來了,她會把你喚醒(因為擋著她門了),這就是阻塞方式。如果小明發現女神不在,立即離開,以後每隔十分鐘回來看一下(採用輪詢方式),不在的話仍然立即離開,這就是非阻塞方式。

(4). 阻塞方式和非阻塞方式唯一的區別: 是否立即返回。

下面我們就來進行更深層次地理解

當對多路復用io進行呼叫時,比如使用poll。需注意的是,poll是系統呼叫,當呼叫poll的時候,其實已經是陷入了核心,是核心執行緒在跑了。因此對於呼叫poll的使用者程序來講,此時是阻塞的。

因為poll的底層實現,是去掃瞄每個檔案描述符(fd),而如果要對感興趣的fd進行掃瞄,那麼只能將每個描述符設定成非阻塞的形式(對於使用者程序來講,設定fd是阻塞還是非阻塞,可以使用系統呼叫fcntl),這樣才有可能進行掃瞄。如果掃瞄當中,發現有可讀(如果可讀是使用者感興趣的)的fd,那麼select就在使用者程序層面就會返回,並且告知使用者程序哪些fd是可讀的。

這時候,使用者程序仍然需要使用read的系統呼叫,將fd的資料,從核心緩衝區拷貝到使用者程序緩衝區(這也是poll為同步io的原因)。

那麼此時的read是阻塞還是非阻塞的呢?這就要看fd的狀態了,如果fd被設定成了非阻塞,那麼此時read就是非阻塞的,否則就是阻塞的。不過程式已經執行到了這時候,不管fd是阻塞還是非阻塞,都沒有任何區別,因為此前的poll,就是知道有資料準備好了才返回的,也就是說核心和緩衝區已經有了資料,此時進行read,是肯定能夠將資料拷貝到使用者程序的緩衝區的。

但如果換種想法,如果poll是因為超時返回的,而我們又對乙個fd(此時fd是被poll輪詢過的)進行呼叫,那麼此時是阻塞還是非阻塞,就非常有意義了。

結論

1.判斷io是同步還是非同步,是看誰主動將資料拷貝到使用者程序

2.select或者poll,epoll,是同步呼叫

關於IO的同步,非同步,阻塞,非阻塞

上次寫了一篇文章 unix io 模型學習。恰巧在這次週會的時候,fp1203 goldendoc成員之一 正好在講解poll和epoll的底層實現。中途正好討論了網路io的同步 非同步 阻塞 非阻塞的概念,當時講下來,大家的理解各不相同,各執己見。搜尋了網路上的一些文章,觀點也各不相同,甚至連wi...

關於IO的同步,非同步,阻塞,非阻塞

上次寫了一篇文章 unix io 模型學習。恰巧在這次週會的時候,fp1203 goldendoc成員之一 正好在講解poll和epoll的底層實現。中途正好討論了網路io的同步 非同步 阻塞 非阻塞的概念,當時講下來,大家的理解各不相同,各執己見。搜尋了網路上的一些文章,觀點也各不相同,甚至連 w...

IO 同步,非同步,阻塞,非阻塞

參考文章 好文推薦 唉最近真是高產似母豬,剛進新公司工作量暫時不飽和,只能每天學學學學學學查漏補缺啦,學習使我快樂哈哈哈哈哈哈哈哈 標題裡的詞彙相信都經常看到,但是能說清楚的估計20個人裡面能有1個就不錯了,網上的資料也是五花八門,大部分描述差不多,很多時候估計作者本身也是似懂非懂,我也看了很多文章...