【问题标题】:Spawned processes becoming defunct衍生进程失效
【发布时间】:2009-04-16 09:31:48
【问题描述】:

我使用 posix_spawnp 从我的主进程中生成子进程。

    int iRet = posix_spawnp(&iPID, zPath, NULL, NULL, argv, environ);   

    if (iRet != 0)
    {       
        return false;
    }

有时,子进程在没有错误的情况下生成后,它会突然失效。怎么会这样?

我使用信号处理程序来获取子进程:

void SigCatcher(int n)
{       
    while(waitpid( -1, NULL, WNOHANG ) > 0);        
}

每当我杀死一个子进程时,我都会手动调用它。

    kill(oProcID, SIGKILL);

    signal (SIGCHLD, SigCatcher);

这是否会导致生成的孩子失效(没有我调用 kill)?

【问题讨论】:

    标签: c++ spawning


    【解决方案1】:

    这个:

    kill(oProcID, SIGKILL);
    
    signal (SIGCHLD, SigCatcher);
    

    看起来像race condition。您需要在杀死子进程之前安装信号处理程序,否则您可能会丢失信号。

    【讨论】:

    • 谢谢。我已经在共享库中实现了信号处理程序。如果我将“信号(SIGCHLD,SigCatcher)”放在构造函数中,它不会被注册。这必须进入 main() 吗?
    • @Gayan:如果您将信号处理程序设置为应用程序在 main 中执行的第一件事,这可能很简单。
    • 它在构造函数中的事实应该无关紧要。但无论如何它应该是主要的(见我的回答)
    • 我需要对“主”应用程序进行最少更改的设置。 “主”应用程序不必处理 SIGCHLD。我正在开发的插件确实如此。有没有办法纯粹通过插件注册信号处理程序? (正如我所说,将 reg. 部分放在构造函数中不起作用)
    • 构造函数没有什么特别之处。它应该仍然可以正常工作。
    【解决方案2】:

    你打过电话吗:

    signal(SIGCHLD, SigCatcher);
    

    还有其他地方吗?

    如果您没有这样做,那么您需要在任何子进程甚至生成之前执行此操作,以确保在这些子进程终止时获得这些子进程。

    正如 Unwind 所指出的,您当前对 killsignal 的调用是错误的。

    典型的用法是:

    signal(SIGCHLD, handler);
    posix_spawnp(...);
    ...
    // do other stuff
    ...
    kill(pid, SIGKILL);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-14
      • 2022-01-03
      • 2010-09-12
      • 1970-01-01
      • 2017-03-19
      • 2012-10-29
      • 1970-01-01
      • 2013-04-13
      相关资源
      最近更新 更多