Waiting for and Exiting from Processes in Linux C

Child processes are scheduled independently of parent processes. As such, we cannot predict in what order parent and child processes will execute. We often want to have a parent process wait until one or more child processes have completed. To do so, we can use the wait family of system calls. Today, we will look at one of the these system calls – the wait() function.

The wait() function waits for any child process to die.  To use wait(), we must include the sys/types.h and sys/wait.h header files.

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

int main(void){

    pid_t child;
    int status;

    if((child = fork())<0){
        printf("Error in creating new process.");
        return 1;
    }


    //in parent process
    if(child>0){
        //pass wait a pointer to int
        wait(&status);
        printf("\nThat's a lot of numbers!\n");
    }

    //in child process
    if(child==0){
        int i = 0;
        while(i++ < 1000){
            printf("%d", i);
        }
    }

    return 0;

}

The wait function accepts a single argument in the form of a pointer to an int.

The wait function returns the process ID of the child process that has ended.

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

int main(void){

    int status;
    pid_t child = fork();
        
    if(child<0){
        printf("problem forking process.\n");
        return 1;
    }

    if(child==0){
        printf("in child process.\n");
        printf("process ID %d\n", getpid());
        printf("parent ID %d\n", getppid());
    }

    if(child>0){
        if(child==wait(&status)){
            printf("child process %d ended.\n", child);
        }
    }

    return 0;

}

Our next program will span multiple processes using a while loop and assign each PID to an array, which we we will use to keep track of what child processes have completed executing.

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

#define NUM_ELEMENTS 10

void removeProcess(pid_t array[], pid_t process, int size);
void printProcesses(pid_t array[], int size);

int main(void){

    pid_t parentID = getpid();

    pid_t childID;

    pid_t IDs[NUM_ELEMENTS];

    int i = 0;

    int status;
    int random;



    while(i < NUM_ELEMENTS){
        childID = fork();
        if(childID==0){
            printf("In child ID %d with parent ID %d\n", getpid(), getppid());
            //generate random number for sleep()
            srand(time(NULL)+(i*2));
            random = (rand() % 15) + 1;
            sleep(random + random);
            //break out of the loop
            break;
        }
        if(childID > 0){
            IDs[i++] = childID;
        }

    }
    
    if(parentID==getpid()){

        while(i > 0){
            childID = wait(&status);
            printf("\nProcess %d exited.\n", childID);
            //remove process from array
            removeProcess(IDs, childID, NUM_ELEMENTS);
            //print out remaining processes
            if(i!=1){
                printf("The following child processes remain active: \n");
                printProcesses(IDs, NUM_ELEMENTS);
            }
            i--;
        }

    }
    


    return 0;

}


//remove the exited process from the array
void removeProcess(pid_t array[], pid_t process, int size){
    for(int i = 0; i < size; i++){
        if(array[i]==process){
            array[i] = 0;
            return;
        }
    }
}

//print the remaining active processes
void printProcesses(pid_t array[], int size){
    for(int i = 0; i < size; i++){
        if(array[i]!=0){
            printf("%d\t", array[i]);
        }
    }
    putchar('\n');
}

Next time we will cover waitpid() as well as interpreting the exit status of child processes.

Be sure and check out my author page on Amazon.com at http://www.amazon.com/Al-Jensen/e/B008MN382O/

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s