Linux:获取孙子的 pid C++

Posted

技术标签:

【中文标题】Linux:获取孙子的 pid C++【英文标题】:Linux: Get the grandchild's pid C++ 【发布时间】:2018-07-26 16:20:41 【问题描述】:

我想创建一个函数,在其中传递一个结构,该结构将存储生成的进程的 pid。

bool spawnHost(string ttyNumber, DeviceData &deviceData)    

   pid_t processID = fork();
   pid_t hostProcessID = -1;
   if (processID == -1)
   
       printf("PID:%d-> Unable to fork a new process. Error: %s", getpid(), strerror(errno));
       return false;
   
   else if (!processID)
   
       printf("PID:%d-> First child spawned. In Parent: %s", getpid(), processID);
       signal(SIGCHLD, SIG_IGN);
       hostProcessID = fork();
       if (hostProcessID == -1)
       
          printf("PID:%d-> Unable to fork a new process. Error: %s", getpid(), strerror(errno));
          return false;
       
       else if (!hostProcessID)
       
          printf("PID:%d-> Starting %s at tty:%s", getpid(), hostAppPath.c_str(), ttyNumber.c_str());
          char *args[] =  (char *) hostAppPath.c_str(), (char *) ttyNumber.c_str(), NULL ;
          execvp(hostAppPath.c_str(), args);
       
       else
       
          printf("PID:%d-> First child spawned. In child: %s", getpid(), hostProcessID);            
          sleep(5);
          exit(0);
       
   
   else
   
      int childStatus;
      waitpid(processID, &childStatus, 0);
      if (WIFEXITED(childStatus))
         printf("PID:%d has exited with exit code %d\n", processID, WEXITSTATUS(childStatus));

      deviceData.setProcessID(hostProcessID);
      return true;
    

这里的要求是宿主进程(在第二个 fork 中产生)不能死亡,即使父进程死亡,宿主进程的 pid 应该存储在传递给 spawnHost() 的结构中功能。目前我无法获得 pid。我这个东东有问题吗?

我什至尝试了以下方法:

bool spawnHost(string ttyNumber, DeviceData deviceData)
   
    string hostAppPath = EXE_PATH;

    signal(SIGCHLD, SIG_IGN);
    pid_t processID = fork();

    if (processID == -1)
    
        printf("PID:%d-> Unable to fork a new process. Error: %s", getpid(), strerror(errno));
        return false;
    
    else if (!processID)
    
        signal(SIGCHLD, SIG_IGN);
        processID = fork();
        if (processID == -1)
        
            printf("PID:%d-> Unable to fork a new process. Error: %s", getpid(), strerror(errno));
            return false;
        
        else if (!processID)
        
            if (setsid() < 0)
            
                printf("PID:%d-> Unable to set new session ID. Error: %s", getpid(), strerror(errno));
                return false;
            

            printf("PID:%d-> Starting %s at tty:%s", getpid(), hostAppPath.c_str(), ttyNumber.c_str());
            char *args[] =  (char *) hostAppPath.c_str(), (char *) ttyNumber.c_str(), NULL ;
            execvp(hostAppPath.c_str(), args);
        
        else
        
            deviceData.setProcessID(processID);
            exit(0);
        
    
    else
           
        return true;
       
    return true;

【问题讨论】:

在 Linux 上,您可以在 /proc 中跟踪进程层次结构。 您需要致电pipe2(fds,O_CLOEXEC),并使用它来传递信息,直到流程开始。我在这里编写了执行此操作的代码:github.com/o11c/python-vterm/blob/master/vterm/c-sources/… @JesperJuhl 我试图获取第二个方法的进程树,因为新进程是在新会话中启动的,因此它嵌套在 init 进程中并且不属于主进程树 @o11c 非常感谢,它成功了。我能够得到孙子 pid。 【参考方案1】:

感谢@o11c 我实现的答案是:

bool spawnHost(string ttyNumber, DeviceData &deviceData)

    int pipefd[2];      
    string hostAppPath = HOST_PATH_PREFIX + HOST_NAME + BUILD_DIR_STRING + HOST_NAME;

    if (pipe(pipefd) == -1)
    
        printf("PID:%d-> IPC not possible as pipe failed");
        return false;
    

    signal(SIGCHLD, SIG_IGN);
    pid_t processID = fork();

    if (processID == -1)
    
        printf("PID:%d-> Unable to fork a new process. Error: %s", getpid(), strerror(errno));
        return false;
    

    else if (!processID)
    
        signal(SIGCHLD, SIG_IGN);
        processID = fork();
        if (processID == -1)
        
            return false;
        
        else if (!processID)
        
            if (setsid() < 0)
            
                printf("PID:%d-> Unable to set new session ID. Error: %s", getpid(), strerror(errno));
                return false;
            
            char *args[] =  (char *) hostAppPath.c_str(), (char *) ttyNumber.c_str(), NULL ;
            execvp(hostAppPath.c_str(), args);
        
        else
        
            /// Write the host pid to the pipe
            close(pipefd[0]);
            write(pipefd[1], &processID, sizeof(processID));
            close(pipefd[1]);
            exit(0);
        
    
    else
    
        close(pipefd[1]); /* Close unused write end */
        read(pipefd[0], &processID, sizeof(processID));
        close(pipefd[0]);
        wait(NULL);

        deviceData.setProcessID(processID);
        return true;
       
    return true;

【讨论】:

以上是关于Linux:获取孙子的 pid C++的主要内容,如果未能解决你的问题,请参考以下文章

C++ Windows - 通过可执行文件路径获取进程的 PID

(Visual C++) 从线程获取 PID

从 C++ 中的可执行路径(或从 hWnd,或从 pid)获取程序名称

如何获取linux下的进程pid列表

jQuery - 获取父母孙子的价值()

linux获取jmeter PID并且kill与启动