检测子进程何时终止使用信号的最佳方法是什么

时间:2018-06-04 05:05:09

标签: c++ linux c++11 embedded-linux

我有一个进程子进程(用fork创建),我想在父进程中知道它死了,并做了些什么。在handle函数中我想使用成员类函数,所以我必须将指针传递给"这个"。

我想过两个方面:

选项1:

使用sigaction;

static RpcCmd* rpcCmdPtr = nullptr;// global pointer to save class  

主要:

  rpcCmdPtr  = this;  
  struct sigaction act;  
  memset(&act, 0, sizeof(act));  
  act.sa_handler = **sigchldHdl**;  
  sigaction(SIGCHLD, &act, 0)  

/* SIGCHLD handler. */  
void **sigchldHdl**(int sig)  
{  
  if(rpcCmdPtr != nullptr)  
  {  
    rpcCmdPtr->sigHandler(sig);  
  }  
}

void RpcCmd::sigHandler(int sig)  
{ // here are some code...}

选项2:

使用另一个线程,将指针传递给"这个"作为参数,并在那里使用signalsfd;

    static void * sigThread(void * arg)  
    {  
    rpcCmd* rpcCmdPtr = static_cast<rpcCmd*>(arg)  
    sigprocmask(SIG_BLOCK, &mask, NULL)  

    /* Create a file descriptor from which we will read the signals. */  
    sfd = signalfd (-1, &mask, 0);  

    while (1) {  
        struct signalfd_siginfo si;  
        res = read (sfd, &si, sizeof(si));  
        if (si.ssi_signo == SIGCHLD)  
            // more code ...  
    } 

我想知道 WHAT 是最好的方式,为什么

提前致谢。

2 个答案:

答案 0 :(得分:3)

仔细阅读signal(7)signal-safety(7)(并记住大多数C ++标准库 - 包括newcontainers等......都是基于异步信号安全函数,如malloc,所以你通常不能从信号处理程序调用这些C ++函数)

你忘记了更便携的选项3:

  • 在流程初始化时,创建一个pipe(7)(到&#34;自我&#34;流程)

  • 在输入event loop之前安装该管道的读处理程序(它将read(2)个字节)

  • 安装(使用sigaction(2))信号的信号处理程序,只需write(2)一个或几个字节进入管道。请注意,write async-signal-safe。

这种方法由Qt提出,请参见其Calling Qt Functions From Unix Signal Handlers页面。

BTW,许多事件循环库(通常高于poll(2) ...)已经处理SIGCHLD

答案 1 :(得分:1)

option 1是邪恶的。

  1. 只能在信号处理程序中调用async-signal-safe函数。在信号处理程序中无法调用许多函数,例如malloc freeprintf

  2. 信号处理程序必须是可重入的,RpcCmd::sigHandler可能不可重入