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 */
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章