1

I am currently taking a Computer Systems class and am having trouble with a homework problem. I have to create this specific process tree:

Process Tree

I also need it to stay in this state for a while (using sleep()) so a user can look it up in the terminal using pstree and see that it exists. Then it must terminate backwards (First D, then B, then C). So far, I can make the tree, but the C term terminates before the rest of the tree is made so I only end up with A->B->D. I know this is happening because of my exit(1) line, but I don't know where else to put this or if there is another way.

Code I have so far:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main() {

int status = 0;
printf("I am: %d\n\n", (int)getpid());
pid_t pid = fork(); // fork a child

if(pid == 0)
{
    printf("Hi I'm process %d and my parent is %d\n",getpid(),getppid());
    exit(1);
}
else
{
    pid_t childPid = wait(&status);
    int childReturnValue = WEXITSTATUS(status);
    printf("parent knows child %d finished with return value %d\n\n", (int) childPid, childReturnValue);

    pid_t pid = fork(); // fork a child
    if (pid == 0)
    {
        printf("Hi I'm process %d and my parent is %d.\n", getpid(), getppid());
        pid = fork(); // fork a child
        if (pid == 0)
        {
            printf("Hi I'm process %d and my parent is %d.\n",getpid(),getppid());
            exit(3);
        }
        else
        {
            pid_t childPid = wait(&status);
            int childReturnValue = WEXITSTATUS(status);
            printf("parent knows child %d finished with return value %d\n\n", (int) childPid, childReturnValue);
        }
        exit(2);
    }
    else
    {
        pid_t childPid = wait(&status);
        int childReturnValue = WEXITSTATUS(status);
        printf("parent knows child %d finished with return value %d\n\n", (int) childPid, childReturnValue);
    }
}

return 0;
}

Here is the output I am currently getting:

I am: 2827

Hi I'm process 2828 and my parent is 2827
parent knows child 2828 finished with return value 1

Hi I'm process 2829 and my parent is 2827.
Hi I'm process 2830 and my parent is 2829.
parent knows child 2830 finished with return value 3

parent knows child 2829 finished with return value 2

Ideally, the line "parent knows child 2828 finished with a return value 1" should be all the way at the end. Thanks in advance!

0

You have to use sleep to prevent C to quit immediately. But in your structure, you have A waiting for C to quit before it spawns B and D.

So :

  • put the wait bloc for C at the same place as the wait bloc for B
  • add a sleep before the exit of C (and also before the exit of B and D)
  • as you don't want to wait for B for double of the time, ensure the sleep of B is before the wait of D
  • to get the correct return value for each sub-process, you should use waitpid instead of wait.

Here is the full code :

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

#define SLEEP_TIME 5

int main() {

int status;
printf("I am: %d\n\n", (int)getpid());
pid_t c_pid = fork(); // fork a child

if(c_pid == 0)
{
    printf("Hi I'm process C (%d) and my parent is %d\n",getpid(),getppid());
    sleep(SLEEP_TIME);
    exit(1);
}
else
{
    pid_t b_pid = fork(); // fork a child
    if (b_pid == 0)
    {
        printf("Hi I'm process B (%d) and my parent is %d.\n", getpid(), getppid());
        pid_t d_pid = fork(); // fork a child
        if (d_pid == 0)
        {
            printf("Hi I'm process D (%d) and my parent is %d.\n",getpid(),getppid());
            sleep(SLEEP_TIME);
            exit(3);
        }
        else
        {
            // sleep before wait - actually no effect as the wait for D also waits for SLEEP_TIME
            sleep(SLEEP_TIME);
            // Wait for D to quit
            waitpid(d_pid, &status, 0);
            int DReturnValue = WEXITSTATUS(status);
            printf("parent knows child D (%d) finished with return value %d\n\n", (int) d_pid, DReturnValue);
        }
        exit(2);
    }
    else
    {
      sleep(SLEEP_TIME);

      // Wait for B to quit
      waitpid(b_pid, &status, 0);
      int BReturnValue = WEXITSTATUS(status);
      printf("parent knows child B (%d) finished with return value %d\n\n", (int) b_pid, BReturnValue);

      // Wait for C to quit
                                    waitpid(c_pid, &status, 0);
      int CReturnValue = WEXITSTATUS(status);
      printf("parent knows child C (%d) finished with return value %d\n\n", (int) c_pid, CReturnValue);
    }
}

return 0;
}

Here is the corresponding output :

I am: 24450

Hi I'm process C (24451) and my parent is 24450

Hi I'm process B (24452) and my parent is 24450.

Hi I'm process D (24453) and my parent is 24452.

parent knows child D (24453) finished with return value 3

parent knows child B (24452) finished with return value 2

parent knows child C (24451) finished with return value 1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.