[英]EAGAIN on a blocking read system call on regular file
因此,这是一个奇怪的案例,我有时会看到却无法找出原因。
我们有一个从常规文件读取的C程序。 还有其他写入同一文件的进程。 该应用程序基于以下事实:在Linux中,写操作是原子的,最大写操作大小为4096字节。
该文件未使用非阻塞标志打开,因此我的假设是读取将被阻塞。
但是有时在启动过程中,我们会在errno
看到“ 资源暂时不可用 ”错误。 读取的!= -1返回的大小,但部分读取的大小。
错误消息如下所示:
2018-08-07T06:40:52.991141Z, Invalid message size, log_s.bin, fd 670, Resource temporarily unavailable, read size 285, expected size 525
我的问题是:
为什么在阻止文件读取时得到EAGAIN
?
为什么返回值不是-1?
这仅在启动时的初始时间内发生。 此后工作正常。 在这种情况下,有哪些极端情况可以使我们陷入困境?
为什么我们在阻止文件读取时得到EAGAIN?
您不是(请参阅下文)。
为什么返回值不是-1?
因为操作没有失败。
如果对read()
的调用失败,则errno
的值仅带有合理的值。 当且仅当返回-1
对read()
调用失败。
返回值
成功后,将返回读取的字节数(零表示文件末尾),并且文件位置以该数字前移。 如果此数目小于请求的字节数,这不是错误;
[...]
如果出错,则返回-1,并正确
errno
。
read()
常见模式是
char buffer[BUFFER_MAX];
char * p = buffer;
size_t to_read = ... /* not larger then BUFFER_MAX! */
while (to_read > 0)
{
ssize_t result = read(..., p, to_read);
if (-1 == result)
{
if (EAGAIN == errno || EWOULDBLOCK == errno)
{
continue;
}
if (EINTR == errno)
{
continue; /* or break depending on application design. */
}
perror("read() failed");
exit(EXIT_FAILURE);
}
else if (0 < result)
{
to_read -= (size_t) result;
p += (size_t) result;
}
else if (0 == result) /* end of file / connection shut down for reading */
{
break;
}
else
{
fprintf(stderr, "read() returned the unexpected value of %zd. You probably hit a (kernel) bug ... :-/\n", result);
exit(EXIT_FAILURE);
}
}
If (0 < to_read)
{
fprintf(stderr, "Encountered early end of stream. %zu bytes not read.\n", to_read);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.