gpt4 book ai didi

c - EAGAIN 对常规文件的阻塞读取系统调用

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:50:30 24 4
gpt4 key购买 nike

所以,这是一个我有时看到但无法找出原因的奇怪案例。

我们有一个从常规文件读取的 C 程序。还有其他进程写入同一个文件。该应用程序基于这样一个事实,即写入在 Linux 中是原子的,写入大小高达 4096 字节。

文件未使用非阻塞标志打开,因此我的假设是读取会阻塞。

但有时在启动过程中,我们会在 errno 中看到“Resource temporary unavailable”错误设置。读取返回的大小!= -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. 这仅在启动的初始时间发生。此后它工作正常。哪些极端情况会让我们陷入这种境地?

最佳答案

Why are we getting EAGAIN on blocking file read ?

你不是(见下文)。

Why is the return value not -1 ?

因为操作没有失败。

如果 read() 调用失败,errno 的值 携带一个合理的值。当且仅当返回 -1 时,对 read() 的调用才会失败。

来自Linux man-page for read() :

RETURN VALUE

On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested;

[...]

On error, -1 is returned, and errno is set appropriately.

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);
}

关于c - EAGAIN 对常规文件的阻塞读取系统调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51740161/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com