【问题标题】:Waitpid interrupted by system callWaitpid 被系统调用中断
【发布时间】:2016-02-01 20:47:44
【问题描述】:

我正在派生一个子进程以使用execve 运行命令。我正在安装和定义 3 个信号处理程序:SIGCHLD、SIGINT 和 SIGSTP,如下所示:

void sigchld(int sig)
{
while((pid=waitpid(-1,&stat,WNOTRACE|WNOHANG))>0)
{
  if(WIFEXITED(stat))
    //normal exit: Delete child from job list
  if(WIFSIGNALED(stat))
    //interrupted by signal: delete job from job list
  if(WIFSTOPPED(stat))
   //Stopped: put child in background
 }
}

//SIGINT Handler:
kill(-pid,sig)

//SIGSTOPPED Handler:
kill(-pid,sig)

现在,当我运行一个进程并将其放入后台(ctrl z)循环(100 次)时,大多数情况下我会收到错误:waitpid error: Interrupted system call

为什么我会得到这个?

【问题讨论】:

  • 请显示完整的代码。如图所示的代码没有发出“waitpid error: Interrupted system call”
  • waitpid() 通过WNOHANG 预计不会因EINTR 而失败。

标签: c process fork sigchld


【解决方案1】:

中断的系统调用:

如果进程在“慢”系统调用中被阻塞时捕获信号,则系统调用被中断。

问题是waitpid函数由于收到调用进程发送的信号而中断。

waitpid 是一个中断的系统调用。所以,中断系统调用的问题是我们现在必须明确地处理错误返回。

您必须使用 errno 处理 waitpid 中的错误。

中断的系统调用意味着,例如,read 语句被执行,read 将从 stdin 读取输入,在读取之间有一个信号发生,现在系统必须处理那个信号,现在 read 将是完成,并将 errno 设置为 EINTR。

【讨论】:

    【解决方案2】:

    我也有这个问题。当我注册我的处理程序时,我使用了一个 sigaction 处理程序,它看起来与这里的情况有点不同。就我而言,我没有包含 SA_RESTART 标志。包含这个处理程序意味着系统调用会在中断时自动重新启动。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-19
      • 2015-01-09
      • 1970-01-01
      • 2011-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多