所以,这是一个奇怪的案例,我有时会看到并且无法弄清楚原因。
我们有一个从常规文件中读取的C程序。还有其他进程写入同一个文件。该应用程序基于以下事实:在Linux中写入是原子的,写入大小最多为4096字节。
该文件未使用非阻塞标志打开,因此我的假设是读取将被阻塞。
但有时在启动期间,我们会在errno
中看到“资源暂时不可用”错误集。并且read!= -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
?为什么我们在阻止文件读取时获得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);
}