首页 > 解决方案 > 我应该在 /proc 中读取文件时处理 EINTR

问题描述

在 Linuxread()中调用可以返回-1EINTR放入errno. 我理解为什么它会发生在管道或套接字上。但是 proc 文件系统中的文件呢?我们真的可以EINTR边读边读吗?

我试图在开源中搜索,发现它在某个地方被处理:

https://github.com/Distrotech/libaudit/blob/distrotech-libaudit/lib/libaudit.c#L700 https://github.com/mmalecki/procps/blob/master/proc/readproc.c#L517

但在某处不是:

https://github.com/slicer69/sysvinit/blob/master/sysvinit/trunk/src/bootlogd.c#L303

它是否取决于 /proc 中的特定文件,如果是,我在哪里可以阅读到这个?或者这种处理总是多余的,或者跳过处理可能是一个错误EINTR

标签: clinux

解决方案


的文档对read底层文件系统没有区别,无论如何它都可以返回-1。因此,您应该处理它。

你如何处理它取决于你。例如,您可以选择退出程序,通知用户失败。或者您可以重试read假设这是一个临时问题,例如:

int interrupted = 1, limit = 5, result;
while (interrupted) {
    result = read(...);
    interrupted = (result == -1) && (errno == EINTR) && (limit-- > 0);
}

这将在放弃之前尝试多次读取文件(假设失败原因是EINTR- 任何其他原因立即退出循环)。当循环退出时,您要么成功读取(result > 0),要么读取不成功并errno设置为原因)。

您还可以将该代码重构为一个函数来为您完成繁重的工作,例如使用我之前用于此目的的函数:

ssize_t interruptibleRead(
    int     fd,             // Standard read parameters.
    void    *buf,
    size_t  count,
    size_t  limit,          // Maximum attempts.
    size_t  msDelay,        // Initial delay after interrupted read.
    size_t  msDelayDelta    // Extra delay added for each interrupted read.
);

这样可以避免在代码中添加复杂的循环,只需将read调用替换为interruptibleRead.


推荐阅读