【问题标题】:Understanding SIGCHLD when the child process terminates了解子进程终止时的 SIGCHLD
【发布时间】:2013-01-10 20:13:47
【问题描述】:

我无法理解以下程序的输出。我观察到子进程返回后,父进程在等待()之前没有休眠 3 秒。如果 SIGCHLD 设置为默认处理程序,则它会休眠 3 秒,调用等待并按预期返回。这里到底发生了什么??

# include <unistd.h>
# include <sys/types.h>
# include <stdio.h>
# include <sys/wait.h>
# include <signal.h>

void handler(int sig) {
printf("Iam in handler ...\n");
}

main() {

int status;
pid_t pid;

struct sigaction act;
//act.sa_flags=SA_NOCLDSTOP;
act.sa_handler=handler;
sigaction(SIGCHLD,&act,NULL);

if(!fork()) {
printf("child process id is  %d\n",getpid());
 return 1;
}  

printf("xxx ...\n");
sleep(3);
pid = wait(&status);
printf("process terminated is %d\n",pid);

}

output::

xxx ...
child process id is  2445
Iam in handler ...
process terminated is 2445

【问题讨论】:

    标签: c linux


    【解决方案1】:

    来自man for sleep()

    sleep() 使调用线程休眠,直到 seconds 秒过去或没有被忽略的信号到达。

    您的孩子终止会导致一个信号唤醒您。

    来自sleep()的返回值:

    如果请求的时间已经过去,则为零,或者如果调用被信号处理程序中断,则剩余的休眠秒数。

    如果你想帮助你“完成”睡眠,可以使用。

    unsigned sleep_time = 3;
    ...
    while((sleep_time = sleep(sleep_time)) > 0) {}
    pid = wait(&status);
    ...
    

    【讨论】:

      【解决方案2】:

      当子进程死亡时,SIGCHLD 会发送给父进程。在您的情况下,它会中断 sleep 并且看起来好像进程没有休眠。

      问题的要点:sleep 在被信号中断时不会重新启动。

      【讨论】:

      • 感谢您的回答。还有一个疑问-我从帖子中读到重新启动系统调用取决于其定义的实现,并且某些系统调用根本不会重新启动。这是真的吗?重启系统调用和调用同一个调用两次一样吗??
      • @Goutham 不一样。将其视为“一个试图不返回 EINTR 的信号。是的,信号重启主要取决于实现。
      猜你喜欢
      • 2011-01-21
      • 1970-01-01
      • 1970-01-01
      • 2013-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      相关资源
      最近更新 更多