0

Are there 3 child processes and 1 parent process? What does the two different waitpid do, and why are there two of them?

int main()
{
    pid_t pid;

    int status, counter = 4;
    while(counter > 0)
    {
        pid = fork();
        if(pid)
        {
            counter /= 2;
        }
        else
        {
            printf("%d", counter); /* (1) */
            break;
        }
    }
    if(pid)
    {
        waitpid(-1, &status, 0);
        counter += WEXITSTATUS(status);
        waitpid(-1, &status, 0);
        counter += WEXITSTATUS(status);
        printf(";%d", counter); /* (2) */
    }
    return counter;
}

the second printf after the waitpid prints 3, 5, 6, 34, 52, 61 (excluding the semicolon). Im not sure how there are two digits printing. I know the second digit is probably coming from the printf in the while loop.

  • Put a prefix before the `printf` in the while loop, so you can tell where it starts. – Barmar Dec 15 '13 at 12:25
  • 1
    Note that some children will also fork. – egur Dec 15 '13 at 12:33
  • 2
    @egur how so? `fork()` is only called in a piece of code that requires `counter > 0` after the fork, the child (with `pid == 0`) breaks out of the loop that performs the `fork()`. – mah Dec 15 '13 at 12:47
  • My mistake, long day. didn't see the break; – egur Dec 15 '13 at 12:49
  • @NeilBharatPatel when I run your code, my output is `412;5`. Notice that my output order (4, 1, 2) is not what you would expect -- this is normal though, you aren't controlling the synchronization of your children. You will get a more accurate (time-wise) view of the output if you flush the output after each print (fflush, or just include \n at the end) but that might not be enough... true synchronization (waiting on a mutex that governs access to the output resource) would be much better. – mah Dec 15 '13 at 12:58

1 Answers1

1

Yes, there are 3 child processes and 1 parent. Children return 4, 2, 1.

To collect all statuses, you could use a while loop:

if(pid)
{
  while (waitpid(-1, &status, 0) != -1) /* ignoring signals, errors */
    counter += WEXITSTATUS(status);
}
return counter;

Parent returns 7 in this case.

If you use only two waitpid() calls then they may return any pair from {4,2,1} set e.g., {4,1} or {2,1} so parent prints ;5 and ;3 correspondingly.

Due to stdio buffering and fork() interaction, the output may multiply. See printf anomaly after “fork()”

Either fflush() before fork() or use write/_exit in children instead.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670