Home > OS >  How to make a process tree in C
How to make a process tree in C

Time:10-04

I want to make a process tree like the picture below. I wrote the code below but if you look at the PIDs, you'll find there's a problem!

process tree here

Process tree if you can't view the image:

//A-B      (A parent of B)
//A-C
//B-D
//D-E
//D-F

My code:

void child(int index, int level, pid_t parent) {  // this is going to be called recursively by all child processes
    pid_t cpid[3];
    int i = 0;
    pid_t Lparent = getpid();
    if (index == 0 && level == 1) {     // this is B
        if ((cpid[i] = fork()) == 0) {  // D is going to execute this
            child(i, 2, Lparent);
        }
        sleep(3);
        for (i = 0; i < 1; i  ) {  // B will kill D
            kill(cpid[i], SIGKILL);
        }
        printf("My PID: %d, My Parent's PID:%d\n", getpid(), parent);  // this is B
        sleep(7);
    } else if (index == 0 && level == 2) {  // this is D
        for (i = 0; i < 2; i  ) {
            if ((cpid[i] = fork()) == 0) {
                child(i, 3, Lparent);
            }
        }
        sleep(5);
        for (i = 0; i < 2; i  ) {
            kill(cpid[i], SIGKILL);
            printf("My PID: %d, My parent's PID:%d\n", getpid(), parent);
            sleep(5);
        }
    } else {
        printf("My PID: %d, My Parent's PID:%d\n", getpid(), parent);
        sleep(10);
    }
}

int main() {
    pid_t cpid[2];
    pid_t root = getpid();
    int i = 0;
    for (i = 0; i < 2; i  ) {
        if ((cpid[i] = fork()) == 0) {
            child(i, 1, root);
        }
    }
    sleep(8);
    for (i = 0; i < 2; i  ) {
        kill(cpid[i], SIGKILL);
    }
    printf("My Pid: %d\n", getpid());

    return 0;
}

My output:

My PID: 211, My Parent's PID:206
My PID: 213, My Parent's PID:212
My PID: 214, My Parent's PID:212
My PID: 210, My Parent's PID:206
My Pid: 206

Does anyone know how I can fix this?

CodePudding user response:

#include <unistd.h>
#include <signal.h>

void child(int index, int level, pid_t parent){ //this is going to be called recursively by all child processes
        pid_t cpid[3]; int i = 0; pid_t Lparent = getpid();
        if(index == 0 && level == 1){ //this is B
                        if( (cpid[i]=fork()) == 0){//D is going to execute this
                                child(i, 2, Lparent);
                }
                sleep(3);
                for(i=0; i<1; i  ){ //B will kill D
                        kill(cpid[i], SIGKILL);
                }
                printf("My PID: %d, My Parent's PID:%d\n", getpid(), parent);//this is B
                sleep(7);
        }
    else if(index == 0 && level == 2){ //this is D
                for(i = 0; i < 2; i  ){
                        if((cpid[i]=fork()) == 0){
                        child(i, 3, Lparent);
                }
        }
        sleep(5);
                for(i=0; i<2; i  ){
                        kill(cpid[i], SIGKILL);
                        printf("My PID: %d, My parent's PID:%d\n", getpid(), parent);
                        sleep(5);
            }
        }    
        else{ 
                printf("My PID: %d, My Parent's PID:%d\n", getpid(), parent);
                sleep(10);
        }
}

int main(){

        pid_t cpid[2];
        pid_t root = getpid(); 
        int i=0;
        for(i=0; i<2; i  ){
                if( (cpid[i]=fork()) == 0){
                        child(i,1,root);
                }
        }
        sleep(8); 
        for(i=0; i<2; i  ){
                kill(cpid[i],SIGKILL);
        }
        printf("My Pid: %d\n", getpid());

return 0;
}

CodePudding user response:

A much simpler and easier-to-debug way to create process trees like this in C using fork() is to create a function for each lettered process and have those functions call fork() when appropriate. Using loops like you attempt in your proposed solution is possible, but very tricky and hard to read, especially since there doesn't appear to be a useful pattern in this tree.

This is an example of a function to perform the duties of A by calling fork() twice to produce two distinct child processes, one to perform the duties of B, the other C.

#include <stdio.h>
#include <unistd.h>

void B(int parent){
  printf("I am process B. My PID is %d, my parent's PID is %d\n",getpid(),parent);
  
  //Do rest of B's job
}

void C(int parent){
  printf("I am process C. My PID is %d, my parent's PID is %d\n",getpid(),parent);
  
  //Do rest of C's job
}

void A(){
  //A must fork off a process for B and for C
  int A_pid = getpid();
  int pid = fork();

  if(pid == 0) //If I'm the first child so I should call B()
    B(A_pid);
  else if(pid > 0){ //I'm the parent so I need to fork() again
    pid = fork();

    if(pid == 0) //I'm the second child so I should call C()
      C(A_pid);
    else if(pid > 0) //I'm still the parent
      printf("I am process A. My PID is %d and I don't have a parent\n",A_pid);
    else
      ;//Handle fork failing the second time
  }
  else
    ;//Handle fork failing the first time

  //Do the rest of A's job
}

int main(){
  A();
}
  • Related