0

read()如果由于信号中断而失败,下面的代码将重新启动该功能。从中断的read()地方继续读取。因此,如果read()在读取字符之前被中断EOF,它将返回它读取的多少字节?

int r_read(int fd, void *buf, int size)
{
   while((retval=read(fd,buf,size))==-1 && errno ==EINTR);
   return retval;
}  

问候。

4

3 回答 3

3

这就是为什么读取的字节数应该保持为一个总数,以避免中断问题。它对于非阻塞 I/O 也很有用。

{
    int ret = 0, nread;
    char *nbuf = (char *) buf;

    while ((nread = read(fd, nbuf, size)) != 0)
    {
        if (nread > 0)
            ret += nread, nbuf += nread, size -= nread;
        elif (errno != EINTR)
            break;
    }

    return ret;
}
于 2012-11-04T12:32:48.793 回答
2

如果errno == EINTR,则表示read它在根据man页面读取任何数据之前就被中断了。即从我的阅读来看,就流中的数据而言,就好像没有发生read状态。EINTR因此,您似乎可以简单地重试,而不必担心丢失任何字节。我觉得这有点令人惊讶,而且我还没有实际测试过,但这就是手册所说的。

以下是手册页中的实际文本:

EINTR 在读取任何数据之前调用被信号中断;见信号(7)。

编辑:我现在对此进行了测试,我发现如果我中断了读取,EINTR只有在读取任何内容之前被中断时才会返回。否则,它将成功返回,读取的字节数少于请求的字节数。因此,要获得所需的字节数,您将需要重新启动的东西,正如另一个答案所示。

于 2012-11-04T12:31:28.207 回答
0

没有这样的“EOF 字符”,存在文件结束条件,表示读取 0 字节。read只有在等待某事发生时被中断,即底层资源产生任何数据之前,才会设置 EINTR 错误。

由于 EOF 通常会导致read停止等待并返回一个值,read因此不能被中断,如果这样做,它只会返回它所拥有的 - EOF 指示符。如果在等待readEOF时被中断(在底层资源宣布之前),它当然会返回 -1 并设置 EINTR。

于 2012-11-04T15:20:29.097 回答