我见过这样的代码:
again:
if ((n = read(fd, buf, BUFFSIZE)) < 0) {
if (errno == EINTR)
goto again; /* just an interrupted system call */
/* handle other errors */
}
这个想法是,如果系统调用因中断而失败,则重试系统调用。但是,某些系统调用可能会自动重试失败的系统调用并显示
EINTR
,从而使上述代码变得多余。
哪些系统/环境会自动重试因
EINTR
失败的呼叫,哪些系统/环境不会?像上面的例子一样,什么时候手动执行此操作可以提供稳定性,即导致失败的操作完成?
fclose()
和 close()
的答案是 否。 这些函数应该 not 在调用失败后重试。
在失败返回后重试
是错误的做法,因为这可能会导致另一个线程重用的文件描述符被关闭。发生这种情况是因为 Linux 内核总是在关闭操作的早期释放文件描述符,将其释放以供重用;可能返回错误的步骤(例如将数据刷新到文件系统或设备)仅在关闭操作的稍后部分发生。close()
来自 C 标准:
成功调用
函数会导致fclose
指向的流被刷新并关闭关联的文件。流中任何未写入的缓冲数据都会传送到主机环境以写入文件;任何未读的缓冲数据都将被丢弃。无论调用是否成功,流都会与文件解除关联,并且由stream
或setbuf
函数设置的任何缓冲区都与流解除关联(如果是自动分配的,则释放)。setvbuf