skip to Main Content
#include "csapp.h"

int main()
{
        int i;

        for (i = 0; i < 2; i++)
                fork();
        printf("hellon");
        exit(0);
}
/*
 *                .------------------------
 *                |
 *                |
 *                |
 *    .-----------.------------------------
 *    |
 *    |
 *    |           .------------------------
 *    |           |
 *    |           |
 *    |           |
 *    .-----------.------------------------
 *   fork        fork
 *   i=0         i=1
 */

In the process pic, it seems the code will print “hello” four times.
Why print ‘hello’ three times in my centos?

2

Answers


  1. Maybe a fork failed or there is a conflict among the printf. On ideone it correctly prints 4 times.

    enter image description here

    Login or Signup to reply.
  2. Unless there’s something weird in your csapp.h header, you should be getting four lines printed out because after the first iteration of the loop (i == 0 before the increment), the fork() creates two processes, and on the second iteration (i == 1 before the increment), each of those two processes executes fork() to create two more processes.

    When this code is run on macOS 10.14.6, I get 4 lines saying hello:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int main(void)
    {
            int i;
    
            for (i = 0; i < 2; i++)
                    fork();
            printf("hellon");
            exit(0);
    }
    

    Output:

    hello
    hello
    hello
    hello
    

    I’d instrument it far more than the bare minimal code shown in the question, though — like this:

    #include <stdio.h>
    #include <unistd.h>
    
    int main(void)
    {
        int i;
        printf("P0: PID = %d, PPID = %dn", (int)getpid(), (int)getppid());
        fflush(stdout);
    
        for (i = 0; i < 2; i++)
        {
            int pid = fork();
            printf("PF: i = %d, PID = %d, PPID = %d, fork = %dn",
                    i, (int)getpid(), (int)getppid(), pid);
            fflush(stdout);
        }
        printf("Hello: PID = %d, PPID = %dn", (int)getpid(), (int)getppid());
        return(0);
    }
    

    Note the copious use of fflush() to avoid the printf() anomaly after fork().

    An example output I got from this was:

    P0: PID = 5039, PPID = 916
    PF: i = 0, PID = 5039, PPID = 916, fork = 5042
    PF: i = 1, PID = 5039, PPID = 916, fork = 5043
    Hello: PID = 5039, PPID = 916
    PF: i = 0, PID = 5042, PPID = 5039, fork = 0
    PF: i = 1, PID = 5043, PPID = 1, fork = 0
    Hello: PID = 5043, PPID = 1
    PF: i = 1, PID = 5042, PPID = 1, fork = 5044
    Hello: PID = 5042, PPID = 1
    PF: i = 1, PID = 5044, PPID = 5042, fork = 0
    Hello: PID = 5044, PPID = 5042
    

    Note that two of the processes reported PPID = 1 because the parent process (5039) had already exited. It would be feasible/sensible to add a loop to wait for children to die and report their exit statuses.

    #include <sys/wait.h>
    
    …
    
    int corpse;
    int status;
    while ((corpse = wait(&status)) > 0)
    {
        printf("WT: PID = %d, PPID = %d, child %d exited 0x%.4Xn",
               (int)getpid(), (int)getppid(), corpse, status);
        fflush(stdout);
    }
    

    What do you get on CentOS?

    I’m running the program from the command line in a terminal window. If you’re running this from an IDE or something, you might be losing the output from the orphaned processes. Adding the wait() loop would prevent the first process from exiting until all (both) its children had exited, leading to an orderly display of the 4 “Hello” lines. I’ve reworked the output formatting so it is easier to read the output.

    #include <stdio.h>
    #include <sys/wait.h>
    #include <unistd.h>
    
    int main(void)
    {
        int i;
        printf("P0: PID = %5d, PPID = %5dn", (int)getpid(), (int)getppid());
        fflush(stdout);
    
        for (i = 0; i < 2; i++)
        {
            int pid = fork();
            printf("PF: PID = %5d, PPID = %5d, i = %d, fork = %5dn",
                    (int)getpid(), (int)getppid(), i, pid);
            fflush(stdout);
        }
    
        printf("hellon");
        printf("HO: PID = %5d, PPID = %5dn", (int)getpid(), (int)getppid());
        fflush(stdout);
    
        int corpse;
        int status;
        while ((corpse = wait(&status)) > 0)
        {
            printf("WT: PID = %5d, PPID = %5d, child %5d exited 0x%.4Xn",
                    (int)getpid(), (int)getppid(), corpse, status);
            fflush(stdout);
        }
    
        printf("EX: PID = %5d, PPID = %5dn", (int)getpid(), (int)getppid());
        return(0);
    }
    

    Sample output (no orphaned processes):

    P0: PID =  5245, PPID =   916
    PF: PID =  5245, PPID =   916, i = 0, fork =  5248
    PF: PID =  5248, PPID =  5245, i = 0, fork =     0
    PF: PID =  5245, PPID =   916, i = 1, fork =  5249
    hello
    HO: PID =  5245, PPID =   916
    PF: PID =  5248, PPID =  5245, i = 1, fork =  5250
    PF: PID =  5249, PPID =  5245, i = 1, fork =     0
    hello
    HO: PID =  5248, PPID =  5245
    hello
    HO: PID =  5249, PPID =  5245
    EX: PID =  5249, PPID =  5245
    PF: PID =  5250, PPID =  5248, i = 1, fork =     0
    hello
    HO: PID =  5250, PPID =  5248
    EX: PID =  5250, PPID =  5248
    WT: PID =  5245, PPID =   916, child  5249 exited 0x0000
    WT: PID =  5248, PPID =  5245, child  5250 exited 0x0000
    EX: PID =  5248, PPID =  5245
    WT: PID =  5245, PPID =   916, child  5248 exited 0x0000
    EX: PID =  5245, PPID =   916
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search