阻塞式IO與非阻塞IO的區別
1. 阻塞式IO (Blocking I/O)
-
定義
當程序發起一個I/O操作(如讀取文件、網絡數據)時,進程會被掛起(阻塞),直到操作完成或超時才會繼續執行后續代碼。在此期間,程序無法執行其他任務。 -
工作流程
python
復制
data = socket.recv() # 調用recv()后,程序卡在這里等待數據 print("收到數據:", data) # 數據到達后才會執行
-
特點
-
優點:編程簡單,代碼直觀。
-
缺點:資源利用率低(等待期間CPU空閑),不適合高并發場景。
-
-
典型場景
-
簡單的單線程腳本
-
對實時性要求不高的低頻操作(如命令行工具)
-
2. 非阻塞式IO (Non-blocking I/O)
-
定義
程序發起I/O操作后立即返回,無需等待結果。可以通過輪詢或事件通知機制(如select
/epoll
)檢查操作狀態,實現并發處理多個I/O。 -
工作流程
python
復制
socket.setblocking(False) # 設置為非阻塞模式 try:data = socket.recv() # 立即返回,若有數據則返回數據,否則拋異常print("收到數據:", data) except BlockingIOError:print("暫時無數據,繼續處理其他任務") # 程序繼續執行其他邏輯
-
特點
-
優點:提高CPU利用率,支持高并發(如同時處理數千連接)。
-
缺點:編程復雜,需配合多路復用或回調機制。
-
-
典型場景
-
Web服務器(Nginx、Node.js)
-
實時通信系統(WebSocket、游戲服務器)
-
3. 核心區別
維度 | 阻塞式IO | 非阻塞式IO |
---|---|---|
行為 | 調用后卡住,直到I/O完成 | 調用后立即返回,需主動查詢狀態 |
CPU利用率 | 低(等待期間閑置) | 高(可并行處理其他任務) |
并發能力 | 弱(依賴多線程/進程) | 強(單線程即可處理大量I/O) |
實現復雜度 | 簡單 | 復雜(需搭配多路復用或異步框架) |
適用場景 | 低頻、簡單任務 | 高頻、高并發場景 |
4. 技術實現
阻塞式IO示例(C語言)
c
復制
int fd = open("file.txt", O_RDONLY); char buf[1024]; read(fd, buf, sizeof(buf)); // 阻塞在此,直到數據讀取完畢 printf("Data: %s\n", buf);
非阻塞式IO示例(C語言)
c
復制
int fd = open("file.txt", O_RDONLY | O_NONBLOCK); // 設置非阻塞標志 char buf[1024]; while (1) {ssize_t n = read(fd, buf, sizeof(buf));if (n > 0) {printf("Data: %s\n", buf);break;} else if (n == -1 && errno == EAGAIN) {// 數據未就緒,處理其他任務usleep(1000); } }
5. 如何選擇?
-
選阻塞式IO:
-
開發簡單快速的小工具。
-
無需高并發(如本地配置文件讀取)。
-
-
選非阻塞IO:
-
高并發服務器(如Web服務、實時聊天)。
-
需要最大限度利用CPU資源的場景。
-
6. 擴展:同步 vs 異步IO
-
同步IO:程序主動等待I/O結果(阻塞式、非阻塞式均屬此類)。
-
異步IO:程序發起I/O后無需等待,操作系統完成后主動通知(如Linux的
io_uring
、Windows的IOCP
)。