注册

Linux报 “interrupted system call” 异常的原因以及解决办法

Linux中的“interrupted system call”表示由于进程被信号中断而导致了系统调用被中断的情况。这种情况通常发生在进程等待系统调用的返回结果时,同时该进程被处理器外部的中断信号中断了。导致此问题的原因可以是系统出现故障,内存损坏等等。此时,进程无法获得预期的系统调用的结果,并显示“interrupted system call”。

以下是两个常见的出现“interrupted system call”的场景并提供相应的解决方案:

  1. 阻塞式I/O和信号处理器

当信号处理器返回时,它会中断进程的系统调用。如果此时的系统调用没有使用SA_RESTART标志,在信号返回后,它将无法恢复进行,并导致“interrupted system call”。 解决此问题的方法是将SA_RESTART标志设置为1,这样系统调用就能够被恢复。示例如下:

struct sigaction act; 
act.sa_handler = signal_handler; 
sigemptyset(&act.sa_mask); 
act.sa_flags = SA_RESTART; 
sigaction(SIGALRM, &act, NULL); 
  1. 被被中断的read或write事件

当进程被接收到一个信号并且该进程正在执行read或write系统调用时,由于此类调用可能会阻塞进程,从而产生“interrupted system call”。解决方法是在出现此类情况时,重复执行系统调用,并用EINTR标志检查调用是否存在并处理。

ssize_t ret = -1;
do {
    ret = read(fd, buffer, len);
} while (-1 == ret && EINTR == errno);
if (-1 == ret) {
    perror("read");
    exit(EXIT_FAILURE);
}

需要注意的是,当出现中断系统调用时,首先应检查是否存在系统故障等其他问题。只有在确定没有问题的情况下,我们才需要通过以上方法来处理中断系统调用的错误。