Search code examples
clinuxforkwaitpid

Problem to understand how it works theses processes


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.


Solution

  • 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 );`
    }