Thread: waitpid() in loop, not ending correctly

  1. #1
    Registered User
    Join Date
    Mar 2013
    Posts
    20

    waitpid() in loop, not ending correctly

    Hi, I have a small program that will fork 5 children and after the last child is created dispose of them one atthe time in a loop like this:

    Code:
    for(x = 0 ; x < 5 ; x++)
        {
          int waitValue = waitpid(childPid[x], &status, 0);
          printf("waitpid() status: %d\n", status);
          printf("waitpid() return value: %d\n", waitValue);
        }
    the childrens pid is stored in an array childPid

    the result when calling wait like this is:

    waitpid() status: 0
    waitpid() return value: 496
    waitpid() status: 0
    waitpid() return value: 497
    waitpid() status: 0
    waitpid() return value: 498
    waitpid() status: 0
    waitpid() return value: -1
    waitpid() status: 0
    waitpid() return value: -1
    It always works for the 3 first but not for the two last, this is the full code and if anybody can identify why this happens, please share.

    [C] #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/w - Pastebin.com

    thank you

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    waitpid(2): wait for process to change state - Linux man page
    You need to use the likes of WEXITSTATUS(status) to actually get the return status out of all the other bits of information encoded into the status integer.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Run the following version of your code (line 58 is added)
    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <stdlib.h>
    #include <time.h>
    
    int randomSleep()
    {
     srand(time(NULL));
     return (rand() % 100);
    }
    
    /*
     * Main method
     * creates children and prints their info
     */
    int main(void)
    {
     int pid, i, x, maxChildren = 5, status, childPid[5];
    
     for(i = 0 ; i < maxChildren ; i++)
     {
      pid = fork();
    
      if(pid == -1)
      {
       printf("fork() failed! Child number %d was not created. Retrying...\n", i);
       i -= 1;
       sleep(1);
       exit(0); //child creation failed, exit
      }
      else if(pid == 0)
      {
       int currentPid = getpid();
       printf("\nParent PID %d, child %d PID %d, group PID %d\n", getppid(), i, currentPid, getpgrp());
       childPid[i] = currentPid;
    
       exit(0);
      }
      else
      {
       //create a random number from 1-10
       srand(time(NULL));
       int sleepSecond = (rand() % 10) + 1;
    
       //sleep after each child did some work
       printf("sleep for %d sec\n", sleepSecond);
       sleep(sleepSecond);
    
       if(i >= (maxChildren - 1))
       {
        printf("\n5 children created, parent sleeps for 20 secnds...\n");
        sleep(2);
    
        for(x = 0 ; x < 5 ; x++)
        {
          printf("parent thinks pid of child #%d is %d\n", x, childPid[x]);  // This is the new line!
          int waitValue = waitpid(childPid[x], &status, 0);
          printf("waitpid() status: %d\n", status);
          printf("waitpid() return value: %d\n", waitValue);
        }
    
        exit(0); //dont create too many children
       }
      }
     }
     return 0;
    }
    Compare the output with the output of your child processes (focus on the pid's) and then think about how the children are connected with the parent.

    Bye, Andreas

  4. #4
    Registered User
    Join Date
    Mar 2013
    Posts
    20
    So I have to use a pointer to the array so that all children add to the same array?

    creating array like this:
    int *childPid[5];

    when child is created, add to this array like this:
    *childPid[i] = currentPid;

    Then I check if it worked by writing out the added value just after:
    printf("pid from array %d\n", *childPid[i]);

    But for some reason this only prints out the last childs pid from this array, the 4 first just skips printing anything.

    Then my parent loop gives me "segment fault":

    Code:
    for(x = 0 ; x < 5 ; x++)    {
          printf("parent thinks pid of child #%d is %d\n", x, *childPid[x]);  // This is the new line
          int waitValue = waitpid(*childPid[x], &status, 0);
          printf("waitpid() status: %d\n", WEXITSTATUS(status));
          printf("waitpid() return value: %d\n", waitValue);
        }
    This means that the parent can not access the childPid array?

  5. #5
    Registered User
    Join Date
    Mar 2013
    Posts
    20
    nevermind, I discovered that if I used another variable as a pointer it works

    thanks very much all!

  6. #6
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by Gatsu View Post
    This means that the parent can not access the childPid array?
    The parent can access the childPid array.

    The problem is this array is not the same as the childPid arrays in the child processes. After forking 5 times you end up with 6 different arrays all having the same name but they are completely independent from each other. Forking means all the variables from the parent process are copied to the child. But there is no connection because the copies are new objects (in different memory locations).

    You have added the children's pids to the children's arrays. Thus the parent process didn't notice any changes and the array in the parent just contained garbage.

    Bye, Andreas

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. loop not incrementing correctly
    By bobknows in forum C++ Programming
    Replies: 1
    Last Post: 11-14-2012, 12:03 AM
  2. Never ending loop
    By mikeman in forum C++ Programming
    Replies: 3
    Last Post: 02-15-2010, 12:03 PM
  3. Ending after do while loop
    By Chipmunkey in forum C++ Programming
    Replies: 6
    Last Post: 08-25-2007, 01:55 PM
  4. Ending a loop, by pushing SPACE ?
    By The SharK in forum C++ Programming
    Replies: 3
    Last Post: 11-25-2006, 01:53 AM
  5. Problem ending loop
    By carolsue2 in forum C++ Programming
    Replies: 4
    Last Post: 02-16-2006, 12:43 PM