【问题标题】:How to track a process on Unix C++?如何在 Unix C++ 上跟踪进程?
【发布时间】:2017-05-08 02:22:23
【问题描述】:

我有一个启动另一个程序(B) 的程序(A)。

我想要的是每次B接收到信号A时都会将此信号发送给B和B的所有子进程。我真的不知道如何在这里实现一些东西:

1)。如何确定该信号已发送到 B?

2)。如何将此信号保存在变量中?

3)。我如何循环直到 B 还活着?

int main() {
   pid_t pid = fork();
   int32_t num = 0;
   if (pid == 0) {
      static char *argv[] = {"main", NULL};
      execv(argv[0], argv); //start program B
   }
   else{
      while(/*B is alive*/){
          //if program B receives signal
          //I want to send this signal to B and all child processes, 
          //cause B doesn't handle any signals
          if (/*B receives signal*/){
              //save this signal to num.
              kill(pid, num); //???
                              //send signal to parent
                              //useless cause it was already send to B?
              fp = popen((("pgrep -P ") + string(num)).c_str(), "r");
              //pgrep all child processes
              std::vector<int> children;
              while (fgets(buf, 128, fp) != NULL) //getting child pid
                  children.push_back(stoi(string(buf)));
              for(auto a : children)              
                  kill(a, num); //send signal to child
         }
      }
   } 
   return 0;
}

【问题讨论】:

    标签: c++ linux process signals signal-handling


    【解决方案1】:

    恐怕你的问题实在是太宽泛了,涉及的话题太多了。如果可能,我会尽力提供帮助。

    关于信号处理。我通常在我的程序中创建一个单独的线程,专门用于信号处理。这样,我就不会“干扰”主执行了。

    关于如何处理信号,请看这段代码sn-p:

    void    *   threadSignalHandler (){
    int err, signo;
    
    for (;;) {
        err = sigwait(&mask, &signo);
        if (err != 0) {
            syslog(LOG_ERR, "sigwait failed");
            exit(1);
        }
    
        switch (signo) {
        case SIGHUP:
            //Do your stuff here
    
            break;
    
        case SIGTERM:
            //Do your stuff here 
            break;
        default:
            syslog(LOG_INFO, "unexpected signal %d\n", signo);
            break;
        }
    }
    return(0);
    

    }

    再次说明,我通常会生成一个新的基本线程,并以这种方式进行:

        int                 err;
        pthread_t           tid;
    
     /*
        * Restore SIGHUP default and block all signals.
        */
       sa.sa_handler = SIG_DFL;
       sigemptyset(&sa.sa_mask);
       sa.sa_flags = 0;
       if (sigaction(SIGHUP, &sa, NULL) < 0)
           err_quit("%s: can′t restore SIGHUP default");
       sigfillset(&mask);
       if ((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0)
           err_exit(err, "SIG_BLOCK error");
    
    
    
        /*
        * Create a thread to handle SIGHUP and SIGTERM.
        */
       err = pthread_create(&tid, NULL, threadSignalHandler, 0);
       if (err != 0)
           err_exit(err, "can′t create thread");
    

    所以,回答你的 3 个问题:

    A) 使用我提供的代码,它已经过测试并且我知道它可以工作。

    B) 只是 修改线程处理程序以存储接收到的信号(变量 签名)

    C) 请看这里,有统一的方法可以做 它,根据posix标准 (Check if process exists given its pid)

    【讨论】:

    • 信号必须在所有其他线程中被阻塞,而您的代码不会。
    • 正确,我没有包括初始部分。我相应地修改了帖子。
    • @MaurizioBenedetti 感谢您的详细回答!
    • 我很高兴雅芳,我很高兴能提供帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-31
    • 2012-09-14
    • 1970-01-01
    • 2021-03-22
    相关资源
    最近更新 更多