【问题标题】:How to manage reads with signals in C?如何使用 C 中的信号管理读取?
【发布时间】:2015-06-27 14:11:39
【问题描述】:

我正在以这种方式从文件中读取整数:

int v, num;
    for(;;) {
        v = read(fd, &num, sizeof(int));
        if (v == -1) {
            fprintf(stderr, "Error in read()\n");
            exit(EXIT_FAILURE);
        }
        if (v == 0) 
            break;
        [...]
    }

如果信号到达会发生什么? 如何管理 errno == EINTR?如果 errno==EINTR,我是否必须重复阅读?

【问题讨论】:

标签: file integer signals errno eintr


【解决方案1】:

如果你没有弄乱信号,你就不必担心它。原因如下:信号的操作是终止、忽略或调用处理程序(或停止/继续,但让我们忽略这些),因此,除非您明确捕获任何信号,否则您将永远不必考虑 EINTR - 它仅当read(2) 被您设置、调用并返回的信号处理程序中断时才会发生。

如果你捕捉到了一个信号,那么慢速系统调用是否自动重新启动由SA_RESTART 标志控制,该标志可以在设置信号处理程序之前在struct sigactionsa_flags 字段中设置/取消设置。如果您希望read(2) 和其他人在处理程序返回后自动重新启动,那么您必须指定此标志以保持代码可移植性(默认行为因平台而异)。

在某些情况下,即使设置了SA_RESTART,也有几个接口不会自动重启;参考man 7 signal查看列表。

如果您想知道:慢速系统调用是在某些条件下可以永久阻塞的系统调用:例如,来自终端或套接字的read()s、FIFO 上的open(2)wait(2) 和系列、文件锁定接口,一些ioctl(2) 电话等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 2012-02-25
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多