【问题标题】:How can I handle SIGCHLD?我该如何处理 SIGCHLD?
【发布时间】:2011-11-02 13:23:10
【问题描述】:

我需要正确处理SIGCHLD。如何将它与我现有的代码一起使用?目前我不能等待子进程,除非我使用0 而不是WNOHANG|WUNTRACED

status = 0; 
pid_t child, endID;

if(amp == 1)
        signal( SIGCHLD, SIG_IGN ); 

child = fork(); 

if (child  <  0) {    
        perror("fork() error\n");
        exit(EXIT_FAILURE);

} else if (child == 0) { 
        // do sth here
        perror("error\n");

} else { 
        //sleep(1)

如果我删除 sleep 则第一次执行父项.. 为什么?

【问题讨论】:

  • 你想达到什么目的?
  • 通过编写和安装适当的信号处理函数来允许混合后台和前台进程
  • 信号处理器应该做什么?
  • 杀死或忽略僵尸

标签: c sigchld


【解决方案1】:

这是一个开始(但请阅读下文):

static void
child_handler(int sig)
{
    pid_t pid;
    int status;

    /* EEEEXTEERMINAAATE! */
    while((pid = waitpid(-1, &status, WNOHANG)) > 0)
        ;
}

/* Establish handler. */
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = child_handler;

sigaction(SIGCHLD, &sa, NULL);

当然,这一切毫无意义。如果父母直接无视SIGCHLD,孩子就会默默收割,不会变成僵尸。

引用TLPI:

将 SIGCHLD 的配置显式设置为 SIG_IGN 会导致任何 随后终止的子进程立即被删除 从系统而不是被转化为僵尸

所以这样的事情应该可以为你解决问题:

signal(SIGCHLD, SIG_IGN); /* Silently (and portably) reap children. */

【讨论】:

  • 我应该在哪里调用这个方法?
  • @kanoz 阅读最后一段 :-)
  • 刚刚遇到这个问题,因为我需要处理 SIGCHLD,但我并没有很清楚地知道你给我们的线路应该在哪里调用。因为它不需要任何 pid 或任何东西,我只是把它放在任何地方,对吗?谢谢@cnicutar。
  • @polar 在开始分叉之前的某个地方。
  • 正如您所说:将 SIGCHLD 的配置显式设置为 SIG_IGN 会导致任何随后终止的子进程立即从系统中删除,而不是被转换为僵尸。如何检查和预防这种情况?我认为这件事发生在我身上?
猜你喜欢
  • 2016-10-31
  • 2012-01-13
  • 1970-01-01
  • 2021-03-03
  • 2013-07-07
  • 2020-08-02
  • 1970-01-01
  • 2022-11-19
相关资源
最近更新 更多