如果由于信号中断而导致read()
函数失败,则重新启动read()
函数。 read()
从它被中断的地方恢复读取。 所以如果read()
在读取EOF
字符之前被中断,它将返回多less字节它读取?
int r_read(int fd, void *buf, int size) { while((retval=read(fd,buf,size))==-1 && errno ==EINTR); return retval; }
问候。
这就是为什么读取的字节数应该保持为总数,以避免中断问题。 这对于非阻塞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; }
如果errno == EINTR
,则意味着在根据man
页可以读取任何数据之前, read
被中断。 也就是说,从我的阅读中,就像在流中的数据一样, EINTR
状态的read
就没有发生。 所以好像你可以简单地重试而不用担心丢失了任何字节。 我觉得这有点令人惊讶,而且我还没有真正测试过,但手册中提到这一点。
以下是手册页中的实际文本:
EINTR在读取数据之前,呼叫被信号中断; 见信号(7)。
编辑:我现在测试了这一点,我发现,如果我打断了读, EINTR
只会返回,如果阅读被中断之前已经读取任何东西。 否则,它将成功返回,读取的字节数小于所请求的数量。 所以为了得到你想要的字节数,你将需要重新启动一些东西,正如另一个答案所表明的那样。
这里没有“EOF字符”,表示为0字节的读取结束的文件结束条件。 EINTR错误只有在等待事件发生时才中断read
,即在底层资源产生任何数据之前。
由于EOF通常会导致read
停止等待并返回一个值,因此read
操作不能被中断,如果这样做,它只会返回它所具有的EOF指示符。 如果read
在等待 EOF(在被底层资源公布之前)中断,它当然会返回-1并设置EINTR。