Search code examples
clinuxfork

Why does my fork() doesn't fork a child and output the print statements?


I am writing a c program in Ubuntu, and in the code I am using fork() to generate 5 different children. But, when i compile and run my program, no children are created, and the printf("Test") that I put inside the three if statements (for case fork() == 0, > 0, < 0), only in > 0, there in the output of the printf statements.

Actually a while ago, the fork() runs just fine, but after I continue my work on the program, it suddenly does not work.

Why is this happening and how should I fix it?

for (i = 0; i < proc; ++i){
    printf("In for %d",i);
    // TODO
    int fork_result = fork();
    if (fork_result == 0){ // Create child process
        child_pids[i] = getpid();
        printf("Test 5");
        printf("In if %d",i);
        break;
    }
    else if(fork_result < 0){
      printf("Fork failed");
    }
    else if (fork_result > 0){
      printf("Parent");
    }
}

Well, the expected outcome is that it would contain "Test 5" or "In if"

Actual output:

In for 0In for 1In for 2In for 3In for 4

Which the actual output does not contain any "Test 5"


Solution

  • The child process continues to execute the code of the caller. The caller is most likely not expecting to execute the parent and all the children. You should exit the child before that happens:

    for (i = 0; i < proc; ++i){
        printf("In for %d",i);
        fflush(stdout); // <--- here
        // TODO
        int fork_result = fork();
        if (fork_result == 0){ // Create child process
            child_pids[i] = getpid();
            printf("Test 5");
            printf("In if %d",i);
            exit(0);  // <---- must have this
            break;
        }
        else if(fork_result < 0){
          printf("Fork failed");
        }
        else if (fork_result > 0){
          printf("Parent");
        }
    }
    // without the exit above the child will execute this code:
    Some code
    

    You must flush stdout, otherwise the children and the parent share the same prefix text in buffer, and both wil print the same prefix, when it finally flushes it. Eventually this sharing will confuse anybody trying to analyze the output.

    Note: once there is an exit call, stdout will be flushed correctly.

    Also, note that the different printouts might be interleaved. Putting them on different lines, with a distinguishing prefix (like i and/or pid) can help debugging.

    Look at this run example