문제

I would like to know - if possible - how to get the pid of a process' grandparent (or further).

To be more specific, I want for a process to print its depth in a process tree. For example, when starting with the following:

int main() {
    int creator_id = (int) getpid();
    pid_t pid1 = fork();
    pid_t pid2 = fork();
    pid_t pid3 = fork();        

    //print depth in process tree of each process

    return 0;
}

According to my theory, the tree will look like this:

               0
              /|\ 
             / | \
            /  |  \
           0   0   0
          / \  |            
         0   0 0  
        /            
       0

So my first idea was to somehow see how often I have to go up until I find the creator's pid.

As a little sidenote: I also wondered if it was possible to make the printing from bottom up, meaning that all processes in the deepest level would print first.

올바른 솔루션이 없습니다

다른 팁

how to get the pid of a process' grandparent (or further).

This depends on which operating system you are using, since you use fork() to create new process in your example, I suppose you are using some Unix-like system.

If you are using Linux and know the pid of a process, you could get its parent process' pid from /proc/[pid]/stat, the fourth field in that file. Through this parent-child chain, you could find a process' all ancestors.

Following @Lee Duhem's hint, I made the following function that returns the nth ancestor of the current process (the 2nd ancestor is the grandparent).

/* Get the process ID of the calling process's nth ancestor. */
pid_t getapid(int n) {
  pid_t pid = getpid();

  while(n>0 && pid){ // process with pid 0 has no parent

    // strlen("/proc/") == 6
    // max [pid] for 64 bits is 4194304 then strlen("[pid]") < 7
    // strlen("/stat") == 5
    // then strlen("/proc/[pid]/stat") < 6 + 7 + 5
    char proc_stat_path[6+7+5+1];
    sprintf(proc_stat_path, "/proc/%d/stat", pid);

    // open "/proc/<pid>/stat"
    FILE *fh = fopen(proc_stat_path, "r");
    if (fh == NULL) {
      fprintf(stderr, "Failed opening %s: ", proc_stat_path);
      perror("");
      exit(1);
    }

    // seek to the last ')'
    int c;
    long pos = 0;
    while ((c = fgetc(fh)) != EOF) {
      if (c == ')')
        pos = ftell(fh);
    }
    fseek(fh, pos, SEEK_SET);

    // get parent 
    fscanf(fh, " %*c %d", &pid);

    // close "/proc/<pid>/stat"
    fclose(fh);

    // decrement n
    n--;
  }

  if(n>0)
    return -1;
  else
    return pid;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top