来自man -e 2 wait
调用等待(&status)等价于: waitpid(-1,&status,0);
errno值:
未设置EINTR WNOHANG,捕获未阻塞信号或SIGCHLD;参见信号(7)。
因此,根据我对上面的理解,如果我们在“等待”中被阻塞并接收到一个信号(SIGCHLD),则调用应该返回,并将-1和errno设置为EINTR。尽管运行以下代码段将证明等待实际上是重新启动的(Linux4.15.0-43,glibc2.23):
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
static void sigchld_handler(int signo)
{
const char *const msg = "\nSIGCHLD";
(void)signo;
write(STDERR_FILENO, msg, strlen(msg));
}
int main(void)
{
pid_t wait_ret = 0, pid = 0;
int status = 0, ret = -1;
sigaction(SIGCHLD, &(struct sigaction){
.sa_handler = sigchld_handler,
}, NULL);
if ((pid = fork()) < 0)
{
perror("\nfork: ");
goto Exit;
}
if (!pid)
{
sleep(3);
return 0;
}
if ((wait_ret = wait(&status)) < 0)
{
perror("\nwait: ");
goto Exit;
}
fprintf(stderr, "\nwait done, pid %d", wait_ret);
ret = 0;
Exit:
fprintf(stderr, "\n");
return ret;
}SA_RESTART没有设置-那么为什么‘等待’重新启动。?实际产出:
等待完成,pid 15242
预期我的产出:
SIGCHLD等待:中断系统调用
注kill -CHLD <waiting process>手动从shell将给出预期的结果。
还请注意,在FreeBSD 11.2上运行代码也会给出预期的结果--等待被中断,子退出时出现错误。
发布于 2019-01-15 15:25:05
这里有一种微妙的解释。你必须首先:
成功后,
wait返回终止子进程的进程ID;如果出现错误,则返回-1。
关于errno值的文档需要以这样的方式来解释:在返回-1时表示错误,errno设置为EINTR,解释为SIGCHLD或未阻塞(其他)信号中断了等待。但这并不意味着接收SIGCHLD必然导致wait()失败。特别是,wait()将正常完成,而不是在进程的一个子进程的终止引起SIGCHLD时引发错误。
在对这里的文档过于挑剔之前,请考虑一下
SIGCHLD可以出于儿童终止的其他原因而交付。SIGCHLD从他们不等待的孩子那里中断。文档的措辞似乎也表明,即使信号被阻塞,SIGCHLD也可能导致EINTR中的一个或多个函数失败。我会觉得这样的行为令人惊讶,但请记住我是从哪里开始的:这个结果可能是对EINTR错误的解释之一,但并不一定意味着它实际上可以发生。
https://stackoverflow.com/questions/54200603
复制相似问题