我正在分叉一个子进程以使用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)
现在,当我运行一个进程并将其放在后台(ctrlz)中循环(100次)时,在大多数情况下,我会得到错误:waitpid error: Interrupted system call
为什么我会得到这个?
中断的系统调用:
如果进程在"慢速"系统调用中被阻塞时捕捉到信号,则系统调用被中断。
问题是由于接收到调用进程发送的信号,waitpid函数被中断。
waitpid是一个中断的系统调用。因此,系统调用中断的问题在于,我们现在必须显式地处理错误返回。
您必须使用errno处理waitpid中的错误。
中断的系统调用意味着,例如,执行读取语句,读取将从stdin读取输入,在读取之间发生信号,现在系统必须处理该信号,现在读取将完成,并将errno设置为EINTR。
我也遇到了这个问题。当我注册处理程序时,我使用了一个sigaction处理程序,它看起来与这里的情况有点不同。在我的例子中,我没有包含SA_RESTART标志。包含此处理程序意味着系统调用在中断时将自动重新启动。