当我的孩子进程退出时,如何使用signalfd和epoll来获取事件?

时间:2014-09-01 14:04:58

标签: c linux io signals epoll

我创建了一个sigset_t并将其设置为空,然后将SIGCHLD添加到其中,然后将其设置为BLOCK

sigset_t    sigmask;
sigemptyset (&sigmask);

sigprocmask (SIG_BLOCK, &sigmask, NULL);

然后通过signalfd

创建signalfd4()
int signalfd = signalfd4 (-1, &sigmask, sizeof(sigset_t), SFD_NONBLOCK);

然后将其添加到之前创建的epollfd中:

struct epoll_event      epev;
memset (&epev, 0, sizeof(struct epoll_event));
epev.events        = POLLIN;

int retval = epoll_ctl (epollfd, EPOLL_CTL_ADD, signalfd, &epev);

和retval为0;

最后,我使用epoll_wait(epollfd, ...)等待我的子进程,它通过fork()进行处理,并在没有做任何事情的情况下休眠2秒,然后退出,但没有返回。

有人请给我一些帮助吗?谢谢!

1 个答案:

答案 0 :(得分:1)

设置信号和信号fd后,我发现以下工作:

  epev.fd = sigfd;   // sigfd if from signalfd, need to remember it
  pid_t me = getpid();                                                                                             
  fork();                                                                                                                       

对于父母:

  if ( me == getpid() ) {                                                                                                       
    // parent                                                                                                                   
    while ( 1 ) { // loop of epoll_wait
      retval = epoll_wait ( epollfd, &epev, 1, -1 );

如果这是信号fd,则读取它以查找发送的信号。

      if ( epev.data.fd == sigfd ) {
        struct signalfd_siginfo si;                                                                                             
        while ( 1 ) {                                                                                                           
          int nr = read ( sigfd, &si, sizeof si );                                                                              
          if ( nr != sizeof si ) {                                                                                              
            break;  // done reading from the signal fd
          }                                                                                                                     
          if ( si.ssi_signo == SIGCHLD ) {                                                                                      

做父母在收到SIGCHILD时需要做的事情

          } else {

其他一些信号

          }                                                                                                                     
        }                                                                                                                       
      }                                                                                                                         
    }                                                                                                                           
  } else {                                                                                                                      
  // child    

子代码