繁体   English   中英

在常规文件的阻止读取系统调用上进行EAGAIN

[英]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

我的问题是:

  1. 为什么在阻止文件读取时得到EAGAIN

  2. 为什么返回值不是-1?

  3. 这仅在启动时的初始时间内发生。 此后工作正常。 在这种情况下,有哪些极端情况可以使我们陷入困境?

为什么我们在阻止文件读取时得到EAGAIN?

您不是(请参阅下文)。

为什么返回值不是-1?

因为操作没有失败。

如果对read()的调用失败,则errno的值带有合理的值。 当且仅当返回-1read()调用失败。

Linux手册页的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM