所以,这是一个奇怪的情况,我有时看到并且无法找出原因。
我们有一个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?
这仅在启动的最初时间内发生。此后工作正常。在这种情况下有哪些优势案例可以解决?
答案 0 :(得分:5)
为什么我们在阻止文件读取时获得EAGAIN?
您不是(请参阅下文)。
为什么返回值不为-1?
因为操作没有失败。
如果对errno
的调用失败,则read()
的值仅具有合理的值。仅当返回read()
时,对-1
的调用失败。
返回值
成功后,返回读取的字节数(零表示结束 的文件名),文件位置按此数字前进。它是 如果此数字小于字节数,则不是错误 请求;
[...]
发生错误时,将返回-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);
}