io阻塞之同步 非同步io(客戶端中)

2021-08-02 03:03:27 字數 1477 閱讀 5019

對於同乙個fd,我一邊往他裡面輸入(用fgets函式),一邊讓他接受伺服器的資料,那麼當我recv沒有收到資料時他會一直等待,即阻塞在這裡,那麼他沒辦法接收來自fgets的輸入資料。如圖,我們的應用程式去呼叫這個recv這個函式,當呼叫的時候我們會進入核心層,核心層去檢測我們套接字有沒有傳過來資料,如果沒有資料,那麼會一直等待,知道有資料來了,才把套接字裡的資料返回到應用層。這就是阻塞的情況,那麼我應該如何處理這種情況呢?

我們可以把recv這個操作設定成非阻塞操作,那麼如何設定呢?在recv函式中,最後乙個引數是flag,這個引數可以設定成非阻塞。當設定成非阻塞是應用層與核心層的狀態是圖中的樣子。當我們呼叫recv這個函式的時候,進入核心層後發現套接字沒有資料,那麼我們立即從核心層返回,而不是一直在核心層中等待。那麼返回的資料是什麼呢?我們如何讓應用層知道我們沒有讀到資料呢?當沒有讀到資料的時候,從核心層返回的是乙個識別符號,這個標示符告訴應用層,我們核心沒有資料。如此反覆,當核心層中的套接字突然有資料的時候,我們就不在返回這樣的標示符了,而是資料,那麼這就是一種非阻塞的狀態。

**中是這個樣子,當我們沒有讀到的時候,continue,那麼他會再次去呼叫recv函式去核心中讀取,自動去讀取這個操作是我們的系統自動去執行的,只要我們設定成非阻塞的方式,並且沒有在**中寫return -1,那麼我們會不斷的去嘗試讀取資料。當然我們可以設定乙個超時時間,當我們很長一段時間沒有讀取到資料的時候,我們會去返回,終止這樣的操作。

但是,這種方式的弊端就是浪費資源,我們的操作不斷的從核心轉移到應用,再從應用轉移到核心。我們可以找到更好的方法來代替這種。

我們可以採用一種訊號通知的方式,我們不在應用層去檢測我們套接字有沒有接收到資料,我們將這個任務交給核心處理。那麼,應該怎麼做呢?我們可以在核心中註冊乙個sigio處理函式,當套接字接收到資料的時候,他會去通知我們應用層套接字收到了資料,這個時候我們再去呼叫recv函式去核心層中讀取資料。這是乙個比較好的方法。但是當我們需要處理大量的資料的時候,這種方式還是有一定的不善。

接著上面內容,我們可以用非同步io的方式。如圖,我們運用乙個函式aio_read,用這個函式去讀取核心中套接字收到的資料,這個函式將讀到的資料直接讀到了我們的應用層。

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

同步io 非同步io 阻塞io 非阻塞io,這幾個詞常見於各種各樣的與網路相關的文章之中,往往不同上下文中它們的意思是不一樣的,以致於我在很長一段時間對此感到困惑,所以想寫一篇文章整理一下。posix 可移植作業系統介面 把同步io操作定義為導致程序阻塞直到io完成的操作,反之則是非同步io按pos...

阻塞IO, 非阻塞IO, 同步IO,非同步IO介紹

一 前言 1 我們之前講了io操作什麼時候切換回來呢?我們剛剛講了 函式,這個 函式是當你的程式一遇到io操作,再一切換,這個切換的時候,切換之前你等著io操作完了再回來。2 io 為什麼不阻塞吶?因為io操作是用作業系統完成的,咋們使用者讀乙個檔案,你以為自己的程式開啟乙個檔案,然後去把檔案的內容...

IO之同步 非同步 阻塞 非阻塞

stevens在文章中一共比較了五種io model blocking io nonblocking io io multiplexing signal driven io asynchronous io 由於signal driven io在實際中並不常用,所以我這只提及剩下的四種io model...