2

我正在分叉一个子进程以使用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

为什么我会得到这个?

4

2 回答 2

1

中断的系统调用:

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

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

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

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

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

于 2015-11-02T10:28:02.273 回答
1

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

于 2018-02-28T03:29:48.203 回答