在关于man
的Linux的write()
页面中,它表示如果EINTR
或EAGAIN
write()
将返回{{1} }}。执行-1
时,如果遇到此类错误,可能会重试。在执行read()
时,应该在这种情况下做些什么?
答案 0 :(得分:1)
据我所知,处理此类情况的一种方法是将write()
调用包装在一个函数中,该函数检查返回值以及errno
变量。
EAGAIN
和EINTR
等案例表示write()
失败的情况,因为某些信号中断或O_NONBLOCK
已设置但write()
会阻止。这意味着您可以通过探测write()
状态重试errno
。
我不确定,但是,如果保证write()
最终会成功,如果你坚持(当然,如果你没有得到任何不同的{{}} 1}}状态)。
您可以执行类似
的操作errno
我还看过代码,其中上述情况通过执行
来处理ssize_t insist_write(int fd, const void * buff, size_t cnt)
{
ssize_t ret;
size_t original_cnt = cnt;
while (cnt > 0)
{
ret = write(fd, buff, cnt);
if (ret < 0)
{
// EINTR for interrupted writes, EAGAIN - EWOULDBLOCK for file/socket
// blocking case (see man page)
if ((errno != EINTR) && (errno != EAGAIN) && (errno != EWOULDBLOCK))
return ret;
else
ret = 0;
}
// update buff and remaining bytes to write
buff += ret;
cnt -= ret;
}
return original_cnt;
}
而不是我写的内容,暗示这样的情况将在每个应用程序的基础上处理(一个这样的例子是在返回if (ret < 0) { return ret; }
之前指定最大write()
次尝试次数。
答案 1 :(得分:1)
您可以在EINTR.
如果您处于非阻塞模式,则只能获得EAGAIN/EWOULDBLOCK
,在这种情况下,仅在循环中重试是不合适的。您应该select()
直到套接字变为可写,然后重试。这只能在对等体读取内容时发生,这就是为什么在发送端刻录CPU周期不合适的原因。
答案 2 :(得分:-1)
通过检查write()
或EINTR
,您可以打包到EAGAIN
。在this问题中建议在这些情况下再次尝试write()
的简单循环,并且可能效果很好: