【Linux網路程式設計】網路程式設計常見概念

杨谖之發表於2024-08-28

【Linux網路程式設計】網路程式設計常見概念

阻塞與非阻塞

阻塞 IO:執行的系統呼叫可能因為無法立即完成而被作業系統掛起,直到等待的事件發生為止。如服務端的 accept(),在客戶端未 connect() 時,其一直處於阻塞狀態直至發生為止,但我們可以對監聽的檔案描述符透過 fcntl() 設定 O_NONBLOCK ,這時就能將阻塞 IO 改為非阻塞 IO。

非阻塞 IO:執行的系統呼叫總是立即返回,不管事件是否已經發生。如果事件沒有立即發生,系統呼叫就返回 -1,和出錯的情況一樣。此時必須依據 errno 來區分這兩種情況,對accept()、send() 和 recv() 而言,事件未發生時 errno 通常被設定為 EAGAIN 或者 EWOULDBLOCK,對 connect() 則 errno 被設定為 EINPROGRESS。

同步與非同步

同步 IO:要求使用者程式碼自行執行 IO 操作,即將資料從核心緩衝區讀入使用者緩衝區,或將資料從使用者緩衝區讀入核心緩衝區,而阻塞 IO、IO 複用和訊號驅動 IO 等都屬於同步 IO。

非同步 IO:使用者可以直接對 IO 執行讀寫操作,這些操作告訴核心使用者讀寫緩衝區的位置,以及 IO 操作完成後核心通知應用程式的方式,即由核心完成 IO 操作。

所以我們也可以這樣認為:同步 IO 嚮應用程式通知的是 IO 就緒事件,而非同步 IO 則嚮應用程式通知的是完成事件。

陳碩:在處理 IO 的時候,阻塞和非阻塞都是同步的 IO,只有使用了特殊的 API 才是非同步 IO。

如下則展示了阻塞 / 非阻塞與同步 / 非同步的關係:

image

相關文章