0

Good evening,

I'm programming and testing some things about processes in C with fork() and waitpid() system calls. I understand the behavior with the global variable, but I don't understand why when the second process is finished and back in the first process the variable "i" has the same value as the second process.

And also why when the program go back to the root process, the variable "i" has the value 2.

Here is the code :

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

int total = 0;
int main(int argc, char **argv) {
    int i, pid;

    for(i = 1; i < 3; ++i) {
        pid = fork();

        if(pid == 0) {
            total = total + i;
            printf("\n");
            printf("Child process %d\n", getpid());
            printf("Parent process %d\n", getppid());
            printf("i = %d\n", i);
        } else {
            waitpid(pid, NULL, 0);
        }
    }
    printf("Child process (end) %d\n", getpid());
    printf("Parent process (end) %d\n", getppid());
    printf("total = %d\n", total);
    printf("i = %d\n", i);
    exit(0);
}

And here is the result of the execution

Child process 9191
Parent process 9190
i = 1

Child process 9192
Parent process 9191
i = 2

Child process (end) 9192
Parent process (end) 9191
total = 3
i = 3

Child process (end) 9191
Parent process (end) 9190
total = 1
i = 3

Child process 9193
Parent process 9190
i = 2

Child process (end) 9193
Parent process (end) 9190
total = 2
i = 3

Child process (end) 9190
Parent process (end) 2876
total = 0
i = 3

I have a suggestion : it is that the function waitpid() take the resources to the child process, but it cannot explain the value of the variable "i" in the root process.

I hope that I was clear about my problems and sorry for my little bad english.

Thank you for your answers.

  • 4
    When you `fork()`, the original process and the child *both* continue from the point of the fork, initially with the same state (subject to some exceptions that don't matter here). In particular, in your case both continue to execute the loop, independently. If that doesn't answer the question then I'm afraid you're going to need to explain your more clearly what it is that confuses you. – John Bollinger Nov 09 '18 at 21:47
  • You might find it helpful to draw out a process tree, or to write out a table of events for each of the processes. – John Bollinger Nov 09 '18 at 21:48
  • 1
    `it cannot explain the value of the variable "i" in the root process`. You actually only print `i` of the root process one time at the end. In the loop you only print when `fork()` returns `0` and that only applies for child processes. – Osiris Nov 09 '18 at 21:52
  • OT: When the parameters to `main()` `argc` and `argv[]` are not going to be used, to avoid the compiler outputting warning messages about the unused variables, use the signature: `int main( void )` – user3629249 Nov 10 '18 at 00:23
  • regarding: `if(pid == 0) { total = total + i; printf("\n"); printf("Child process %d\n", getpid()); printf("Parent process %d\n", getppid()); printf("i = %d\n", i); }` at the end of the child process, MUST have an `exit( 0 );` statement, otherwise the execution of the child will continue around the loop – user3629249 Nov 10 '18 at 00:26

1 Answers1

1

the following corrected code:

  1. cleanly compiles
  2. performs the desired functionality
  3. clearly shows that total in the parent is no changed by the child processes

and now, the proposed code:

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

int total = 0;


int main( void )   // <<-- corrected statement
{
    int i, pid;

    for(i = 1; i < 3; ++i) 
    {
        pid = fork();

        if(pid == 0) 
        {
            total = total + i;
            printf( "\n") ;
            printf( "Child process %d\n", getpid() );
            printf( "Parent process %d\n", getppid() );
            printf( "i = %d\n", i );
            exit( 0 );    // <<-- added statement
        } 

        else 
        {
            waitpid( pid, NULL, 0 );
        }
    }

    printf( "Child process (end) %d\n", getpid() );
    printf( "Parent process (end) %d\n", getppid() );
    printf( "total = %d\n", total );
    printf( "i = %d\n", i );
    exit( 0 );
}

the output of the above code is:

Child process 10378
Parent process 10377
i = 1

Child process 10379
Parent process 10377
i = 2
Child process (end) 10377
Parent process (end) 10375
total = 0
i = 3

however, the code fails to check for the error case from the function: fork() so will be open to a major failure if the call to fork() fails. I.E. the code should be (also) checking for a returned value of -1 from the call to fork() and calling

if( pid < 0 )
{
    perror( "fork failed");  
    exit( 1 );`
}
user3629249
  • 16,402
  • 1
  • 16
  • 17