axel_87
axel_87

Reputation: 37

Creation of child processes in C

would it be possible to help me with creation of short program in which parent process produces 1 child process, the child produces the next child, the subsequent child produces the next child, etc. .... so that all children are in total 16. How can I using the pstree command, present the tree of these processes ? Till now I was able to write something like, but I’ not sure if its correct:

int main()
{
    for(int i = 0; i < 16; ++i)
    {
        pid_t pid = fork();
        if(pid != 0)
        {
            waitpid(pid, NULL, 0);
            return 0;
        }
    }

    sleep(5);
    return 0;
}

Upvotes: 1

Views: 88

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 754890

As I noted in a comment, add diagnostic printing to help you understand what's going on. Key values are the loop control, i, the PID and PPID of the process, and the value in the pid variable. You also want to instrument the waitpid() call.

That leads to code like this:

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

int main(void)
{
    for (int i = 0; i < 16; ++i)
    {
        pid_t pid = fork();
        printf("%d: (PPID = %d) - post fork %d: pid = %d\n",
               (int)getpid(), (int)getppid(), i, (int)pid);
        fflush(0);
        if (pid != 0)
        {
            int status;
            int corpse = waitpid(pid, &status, 0);
            printf("%d: (PPID = %d) child %d exited with status 0x%.4X\n",
                   (int)getpid(), (int)getppid(), corpse, status);
            fflush(0);
            return 0;
        }
    }

    printf("%d: (PPID = %d) sleeping\n", (int)getpid(), (int)getppid());
    fflush(0);
    sleep(5);
    return 0;
}

The fflush() calls aren't necessary if you run the output to a terminal. If you run the output through a pipe (like I did when generating the output below), they become crucial. See also printf() anomaly after fork(). If you replaced the return 0; in the if with return i;, you'd also get some interesting information.

Running that program leads to output similar to this:

74830: (PPID = 72799) - post fork 0: pid = 74833
74833: (PPID = 74830) - post fork 0: pid = 0
74833: (PPID = 74830) - post fork 1: pid = 74834
74834: (PPID = 74833) - post fork 1: pid = 0
74834: (PPID = 74833) - post fork 2: pid = 74835
74835: (PPID = 74834) - post fork 2: pid = 0
74835: (PPID = 74834) - post fork 3: pid = 74836
74836: (PPID = 74835) - post fork 3: pid = 0
74836: (PPID = 74835) - post fork 4: pid = 74837
74837: (PPID = 74836) - post fork 4: pid = 0
74837: (PPID = 74836) - post fork 5: pid = 74838
74838: (PPID = 74837) - post fork 5: pid = 0
74838: (PPID = 74837) - post fork 6: pid = 74839
74839: (PPID = 74838) - post fork 6: pid = 0
74839: (PPID = 74838) - post fork 7: pid = 74840
74840: (PPID = 74839) - post fork 7: pid = 0
74840: (PPID = 74839) - post fork 8: pid = 74841
74841: (PPID = 74840) - post fork 8: pid = 0
74841: (PPID = 74840) - post fork 9: pid = 74842
74842: (PPID = 74841) - post fork 9: pid = 0
74842: (PPID = 74841) - post fork 10: pid = 74843
74843: (PPID = 74842) - post fork 10: pid = 0
74843: (PPID = 74842) - post fork 11: pid = 74844
74844: (PPID = 74843) - post fork 11: pid = 0
74844: (PPID = 74843) - post fork 12: pid = 74845
74845: (PPID = 74844) - post fork 12: pid = 0
74845: (PPID = 74844) - post fork 13: pid = 74846
74846: (PPID = 74845) - post fork 13: pid = 0
74846: (PPID = 74845) - post fork 14: pid = 74847
74847: (PPID = 74846) - post fork 14: pid = 0
74847: (PPID = 74846) - post fork 15: pid = 74848
74848: (PPID = 74847) - post fork 15: pid = 0
74848: (PPID = 74847) sleeping
74847: (PPID = 74846) child 74848 exited with status 0x0000
74846: (PPID = 74845) child 74847 exited with status 0x0000
74845: (PPID = 74844) child 74846 exited with status 0x0000
74844: (PPID = 74843) child 74845 exited with status 0x0000
74843: (PPID = 74842) child 74844 exited with status 0x0000
74842: (PPID = 74841) child 74843 exited with status 0x0000
74841: (PPID = 74840) child 74842 exited with status 0x0000
74840: (PPID = 74839) child 74841 exited with status 0x0000
74839: (PPID = 74838) child 74840 exited with status 0x0000
74838: (PPID = 74837) child 74839 exited with status 0x0000
74837: (PPID = 74836) child 74838 exited with status 0x0000
74836: (PPID = 74835) child 74837 exited with status 0x0000
74835: (PPID = 74834) child 74836 exited with status 0x0000
74834: (PPID = 74833) child 74835 exited with status 0x0000
74833: (PPID = 74830) child 74834 exited with status 0x0000
74830: (PPID = 72799) child 74833 exited with status 0x0000

If you were feeling even more fussy, you could add timing to the printing operations — you'd probably need to report at the microsecond level to see much difference.

Upvotes: 1

Related Questions