0

Still new in learning about forks and processes and I have this task to create 3 child processes perform some actions and then the parent should print there exit status as they terminate.

The problem I am having is child 1 is terminating earlier and I dont think i am using wait() correctly.

This is my code:

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

int main( int argc, char *argv[] ) {
    pid_t child1,child2, child3,wpid;
    int child1Status,child2Status,child3Status;

child1 = fork();
   if (child1 == 0){
    float marks[8];
    float average = 0.0;
    float sum = 0.0;
    printf("I am child one my pid is %d \n",getpid());
    printf("Please enter 8 marks and I will calcuate the average and highest mark\n");
    for (int i = 0; i < 8; ++i) {
        printf("%i) ",i+1);
    scanf("%f", &marks[i]);
    sum += marks[i];
}
average = sum / 8;
printf("Average = %.2f and highest = %.2f\n", average,highest(&marks));
exit(1);
}
 else{
        
        child2 = fork();
         if (child2 == 0){
    

char *cmd = "wc";
        char *args[4];
    args[0] = "wc";
    args[1] = "-c";
    args[2] = "test.txt";
    args[3] = NULL;
         execvp(cmd, args);
      
         }
         else
        {
           child3 = fork();
            if (child3 == 0){
        

          char *cmd = "wc";
            char *args[4];
            args[0] = "wc";
            args[1] = -c;
            args[2] = "anotherfile.txt";
            args[3] = NULL;
            execvp(cmd, args);
             }
          else
            {

                
                wait(&child1Status);
                printf(" child one has exited with exit status %d \n", (child1Status >> 8));
                wait(&child2Status);
                printf(" child two has exited with exit status %d \n", (child2Status >> 8));
                wait(&child3Status);
                printf(" child three has exited with exit status %d \n", (child3Status  >> 8));
            }

}

In my current output child 1 says it has been exited before I enter in any marks whereas it should say it has been exited after it prints out the highest and average mark.

I also know that because I am using execvp in child2 and 3 then the exit() code wont run, how i can get the exit status in that case?

I also need to print "parent is finished" once all the child processes have been terminated, how can I be sure that all the child processes have terminated before i print "parent is finished"

edit: replaced the last else block with the following due to the comments

else
            {
                
                waitpid( child1,  &child1Status, 0);
                printf(" child one has exited with exit status %d \n", (child1Status >> 8));
                 waitpid( child2,  &child2Status, 0);
                printf(" child two has exited with exit status %d \n", (child2Status & 0x7F));
                 waitpid( child3,  &child3Status, 0);
                printf(" child three has exited with exit status %d \n", (child3Status & 0x80));
            }

With the following above all 3 child processes exit one after each other at the end which should not be the case

expected output:

I am child 1 please enter 8 marks and i will find the average
I am child 2 here is the word count 
50
child 2 has exited 
i am child 3 here is the word count 
96 
child 3 has exited 
**enter 8 marks by user**
average is 
child 1 has exited
parent has finished

Current output:

 I am child 1 please enter 8 marks and i will find the average
    I am child 2 here is the word count 
    50
  i am child 3 here is the word count 
    96 
**enter 8 marks by user**
    average is 
    child 1 has exited
child 2 has exited
child 3 has exited
william_
  • 1,131
  • 6
  • 20
  • Edit the question to provide a [mre]. It appears you have omitted code essential to examining the problem. – Eric Postpischil May 17 '21 at 06:35
  • If you want to wait for the first child to exit before creating the second child, you should move the `wait(&child1Status);` before the second fork. – mkayaalp May 17 '21 at 06:39
  • @mkayaalp I dont want to wait for the first child to exit before creating other processes. Child 1 is exiting before the code for child 1 has finished running – william_ May 17 '21 at 06:42
  • 1
    The three `wait` calls don't necessarily correspond to child one, two, three as you indicate. It's whoever finishes first. You can use `waitpid` to wait for a specific child. – mkayaalp May 17 '21 at 06:43
  • @mkayaalp please see my edited code , I tried using waitpid which prints the exit status at the end of the code I will also post current output vs expected output – william_ May 17 '21 at 06:52
  • 1
    @william_ Okay, I guess you don't want to wait for them to finish in that order. Maybe use `wait` as before but use the return value to determine which child finished. – mkayaalp May 17 '21 at 07:11

1 Answers1

0

Your code does not even compile due to various mistakes...

Anyway, it looks that you want to show the end of the childs as soon as it occurs. For that, you should loop on wait until there is no more child to wait, and use the return value to know which one has ended:

      ...
      else
        {

        for(;;) {    
            pid_t pid = wait(&child1Status);
            int child_num;
            if (pid == child1) child_num = 1;
            else if (pid == child2) child_num = 2;
            else if (pid == child3) child_num = 3;
            else break;   // no more child to wait...

            printf(" child %d has exited with exit status %d \n",
                   child_num, (child1Status >> 8));
        }
        }
        ...
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252