在網絡編程的 I/O 模型討論中,「同步/異步」與「阻塞/非阻塞」是最容易混淆的四個概念。許多開發者甚至資深工程師,也難以清晰闡述它們的邊界與關聯。本文參考經典著作《UNIX 網絡編程 卷一》第六章,結合內核視角,為你徹底拆解這五種 I/O 模型的本質差異。
書中定義了以下五種可用的 I/O 模型:
一次輸入操作包含兩個階段:
應用調用 recvfrom 後,進程在兩個階段均被掛起睡眠,直到數據複製完成才返回。

紅色標記區域即為進程阻塞等待的過程。
核心語句:「當所請求的 I/O 操作非得把本進程投入睡眠才能完成時,不要把進程投入睡眠,而是返回一個錯誤。」
進程反覆調用 recvfrom,若數據未就緒立即返回 EWOULDBLOCK,需應用層自行輪詢。

雖然 select/epoll 本身是阻塞的,但它阻塞在「監控多個描述符」這一系統調用上,而非具體的 recvfrom。一旦有描述符就緒,再發起真正的讀取。

進程預先註冊信號處理函數,數據就緒時內核發送 SIGIO,進程在信號處理函數中調用 recvfrom。此處略過詳細圖解。

調用 aio_read 後立即返回,內核自動完成「等待數據」與「複製數據」兩個階段,完成後通知進程(回調或信號)。這是唯一在兩個階段均不阻塞進程的模型。

POSIX 給出權威定義:
前四種模型(阻塞、非阻塞、多路復用、信號驅動)本質上都是同步 I/O,它們的區別僅在於「第一階段(等待數據就緒)如何處理」。而異步 I/O 則將兩個階段完全交由內核代勞。
| 概念對 | 核心關注點 | 一句話定義 |
|---|---|---|
| 阻塞 / 非阻塞 | 進程/線程在訪問數據時,數據是否就緒、是否需要等待 | 調用者主動發起請求後,是否立即返回或被掛起睡眠。 |
| 同步 / 異步 | 訪問數據的方式與責任歸屬 | 同步需主動讀寫數據,讀寫過程中仍會阻塞;異步只需接收「操作完成」通知,數據讀寫由內核完成。 |
理解這兩組概念的正交關係,是掌握高性能網絡編程的基石。