Linux下阻塞和非阻塞讀寫

Linux下阻塞和非阻塞讀寫

阻塞讀

ssize_t ret;

vhile (len != 0 && (ret = read(fd, buf, len))!=0) {
    if (ret = -1) {
        if (errno == EINTR)
            continue;
        perror("read");
        break;
    }
    len -= ret;
    buf += ret;
}

這裏處理了5種情況,可以封裝爲一個新的read函數。
read調用原型

ssize_t read(int fd, void *buf, size_t len);
  • 如果返回值 == 0,說明已經達到文件末尾(EOF)[情況1]
  • 如果沒有數據可讀,調用回阻塞(sleep),直到有數據可讀
  • 如果返回值 < 0,說明讀取過程中出錯。例如:
    • EINTR,表示在讀取任何字節之前接收到信號。read調用可以重新執行 [情況2]
    • 非EINTR,表示更嚴重錯誤,不能重新執行read調用 [情況3]
  • 如果返回值 == len,讀取的所有len個字節都被保存到buf中 [情況4]
  • 如果返回值 > 0 且 < len,有可能:
    • 讀取過程中信號中斷/讀取中出錯;
    • 可讀數據大於0字節小於len字節;
    • 在讀取len之前到達了EOF
    • 可以再次執行read調用,把剩餘字節讀入緩衝區或者給出錯誤信息 [情況5]

非阻塞讀

非阻塞讀可以避免沒有數據可讀時阻塞在哪裏,而是立即返回,表示沒有數據可讀。需要額外檢查errno值是否爲EAGIN

char buf[BUFFSIZE];
ssize_t nr;

start:
nr = read(fd, buf, BUFFSIZE];
if (nr == -1) {
	if (errno == EINTR)
		goto start;

	if (errno == EAGAIN)
		/* resubmit later*/
	else
		/* error */
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章