Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux I/O 模型核心概念:同步/非同步與阻塞/非阻塞深度對比

編輯:Linux 教學

同步/非同步與阻塞/非阻塞是兩組正交概念,常被混淆。本文以「銀行辦事」類比,配合 read/write、select/poll、aio 實例,釐清四種組合的行為差異與效能影響。

核心定義

維度關注點銀行類比
同步/非同步「誰來通知完成」同步=自己盯著排隊;非同步=領號碼牌,櫃台廣播通知
阻塞/非阻塞「等待時能不能做別事」阻塞=站著不能動;非阻塞=邊刷手機邊等

同步 I/O

  • 阻塞:read(fd, buf, n) 預設行為。資料未就緒 → 執行緒睡眠,資料到達 → 複製到用戶緩衝 → 返回。
  • 非阻塞:fcntl(fd, F_SETFL, O_NONBLOCK)。資料未就緒 → 立即返回 -EAGAIN,應用需輪詢或配合 select。

同步非阻塞需應用自行「輪詢狀態 → 發起 I/O」,造成用戶態/核心態頻繁切換,效率低。

非同步 I/O

  • 阻塞:select/poll/epoll 配合 timeout=NULL。等待事件 → 阻塞於系統呼叫;事件就緒 → 返回就緒 fd 列表 → 應用發起 read/write(通常不阻塞)。
  • 非阻塞:aio_read/aio_write (POSIX AIO) 或 io_uring (Linux 5.1+)。提交請求 → 立即返回;完成時透過訊號/回調/完成佇列通知。

四種組合對照表

阻塞非阻塞
同步read/write (預設)O_NONBLOCK + read/write 輪詢
非同步select/poll/epoll (timeout=-1)aio_* / io_uring / signalfd + epoll

關鍵釐清

  1. 同步 ≠ 阻塞:可對 fd 設 O_NONBLOCK,同步變非阻塞。
  2. 非同步 ≠ 非阻塞:select(NULL) 會阻塞等待事件;aio 才是真正全非阻塞。
  3. 通知機制 ≠ 處理機制:非同步只負責「通知 fd 就緒」,實際 read/write 仍由應用發起,屬於同步操作。

效能與選型建議

  • 高併發長連線:epoll (非同步阻塞) 或 io_uring (非同步非阻塞) 最佳。
  • 簡單低併發:阻塞 read/write + 多執行緒/多進程 模型開發效率最高。
  • 避免同步非阻塞輪詢:CPU 空轉嚴重,除非極低延遲需求且配合 epoll 邊緣觸發。

程式碼對照

// 同步阻塞
n = read(fd, buf, sizeof(buf));

// 同步非阻塞
fcntl(fd, F_SETFL, O_NONBLOCK);
while ((n = read(fd, buf, sizeof(buf))) == -1 && errno == EAGAIN)
    ; // 忙等或配合 select

// 非同步阻塞 (epoll)
epoll_wait(epfd, events, MAX_EVENTS, -1); // 等待事件
for (e : events) read(e.data.fd, buf, sizeof(buf));

// 非同步非阻塞 (io_uring)
io_uring_sqe *sqe = io_uring_get_sqe(ring);
io_uring_prep_read(sqe, fd, buf, sizeof(buf), 0);
io_uring_submit(ring);
// 稍後從 cqe 取得完成結果

理解兩組概念正交性,才能根據延遲、吞吐、複雜度需求選擇最適 I/O 模型。

Copyright © Windows教程網 All Rights Reserved