4

Been practicing with those system calls, but I stucked into this code:

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

main()
{
    pid_t pid;
    switch(pid = fork())
    {
        case -1:
            printf("fork failed");
            break;
        case 0:  //first child
            printf("\ni'm the first child, my pid is %d", getpid());
            fflush(stdout);
            break;
        default:    //parent
            sleep(5); /** sleep is generating problems **/
            printf("\ni'm the parent process, my pid is %d", getpid());
            printf("\ngenerating a new child");
            fflush(stdout);
            switch(pid = fork())
            {
                case -1:
                    printf("fork failed");
                    break;
                case 0: //second child
                    printf("\nhere i am, the second child, my pid is %d", getpid());
                    break;
                default:  //parent
                    wait((int *)0);
                    printf("\nback to parent, my pid is %d", getpid());
            }
    }

    return 0;
}

The output I'm getting is:

i'm the first child, my pid is 6203
i'm the parent process, my pid is 6202
generating a new child
back to parent, my pid is 6202
Process returned 0 (0x0)   execution time: 5.004 s
Press ENTER to continue

here i am, the second child, my pid is 6204

What I'm trying it's a simple print of these messages managing the timing via sleep(). I can't understand why the program is returning before printing the second child message. The default case(the one right after the second fork) got printed before its child(second) acting on the output like he's ignoring its wait(). Its child therefore got printed after the process returns.

I wasn't able to figure out what's the problem. I've marked sleep() function since if I substitute it with wait((int *)0); the processes flux is working how it was designed to (anyhow, without any timing). At this point I'm not sure anymore about process flux, or the sleep() usage (man pages wasn't that helpful, way too concise to be honest).

init6eb
  • 45
  • 1
  • 1
  • 4

2 Answers2

4

Actually, your call to wait works. It detects the end of the first child process and continues afterwards. If you do two consecutive calls to wait(), you will get the proper behaviour.

Updated test code :

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

main()
{
    pid_t pid;
    int status;
    switch(pid = fork())
    {
        case -1:
            printf("fork failed");
            break;
        case 0:  //first child
            printf("\ni'm the first child, my pid is %d", getpid());
            fflush(stdout);
            break;
        default:    //parent
            sleep(5); /** sleep is generating problems **/
            printf("\ni'm the parent process, my pid is %d", getpid());
            printf("\ngenerating a new child");
            fflush(stdout);
            switch(pid = fork())
            {
                case -1:
                    printf("fork failed");
                    break;
                case 0: //second child
                    printf("\nhere i am, the second child, my pid is %d", getpid());
                    break;
                default:  //parent
                    pid = wait(&status);
                    printf("\nParent detects process %d was done", pid);
                    pid = wait(&status);
                    printf("\nParent detects process %d was done", pid);
                    printf("\nback to parent, my pid is %d", getpid());
            }
    }

    return 0;
}

Output :

i'm the first child, my pid is 30897
i'm the parent process, my pid is 30896
generating a new child

here i am, the second child, my pid is 30940
Parent detects process 30897 was done
Parent detects process 30940 was done
back to parent, my pid is 30896
BenC
  • 8,729
  • 3
  • 49
  • 68
2

The man page for wait says the following:

The wait() function shall suspend execution of the calling thread until status information for one of the terminated child processes of the calling process is available, or until delivery of a signal whose action is either to execute a signal-catching function or to terminate the process. If more than one thread is suspended in wait() or waitpid() awaiting termination of the same process, exactly one thread shall return the process status at the time of the target process termination.

Wait is returning because of the first child.

Jim Clay
  • 963
  • 9
  • 24