Search code examples
cparallel-processingforkoperator-precedence

Parallel programming in C not executing instructions


I need help with C parallel programming, from this graph: graph image

I wrote this code:

#include <stdio.h>
#include <stdlib.h>
int main ()
{
    int r2;
    printf("---------   Program start   ---------");
    printf("\nBlock A instructions"); //block A
    printf("\nBlock B instructions"); //block B
    r2= fork();
    if (r2==0){ //child
        printf("\nBlock E instructions"); //block E
        printf("\nBlock F instructions"); //block F
        exit(0);
    }
    else{
        if (r2>0){ //father
            printf("\nBlock C instructions"); //block C
            printf("\nBlock D instructions"); //block D
            exit(0);
        }
        else printf("\nError");
    }
    printf("\nBlock G instructions"); //block G
    printf("\nBlock H instructions"); //block H
    printf("\n---------   Program finish   ---------");
}

And the output is:

---------   Program start   ---------
Block A instructions
Block B instructions
Block E instructions
Block F instructionsBlock B instructions
Block C instructions
Block D instructions

Why doesn't the program write the other instructions, and why does it write "block B instructions" twice?

--------------------- EDIT: ---------------------

The new code is:

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main ()
{
    printf("---------   Program start   ---------\n");
    printf("Block A instructions\n"); //block A
    printf("Block B instructions\n"); //block B
    fflush(stdout);
    pid_t r2= fork();
    if (r2==0){ //child
        printf("Block E instructions\n"); //block E
        printf("Block F instructions\n"); //block F
        fflush(stdout);
        exit(1);
    }
    else{
        if (r2>0){ //father
            printf("Block C instructions\n"); //block C
            printf("Block D instructions\n"); //block D
            fflush(stdout);
            wait(NULL); //wait for child process to join with this parent, returns no value
        }
        else printf("Error");
    }
    printf("Block G instructions\n"); //block G
    printf("Block H instructions\n"); //block H
    printf("---------   Program finish   ---------");
    return 0;
}

The output now is:

---------   Program start   ---------
Block A instructions
Block B instructions
Block E instructions
Block F instructions
Block C instructions
Block D instructions
Block G instructions
Block H instructions
---------   Program finish   ---------

Sometimes the C and D instructions are written before the E and F instructions, is it normal or should it always be EF --> CD ? Btw is the code good or are there some mistakes? I compiled it with -Wall and I don't get any error messages


Solution

  • <stdio.h> is buffered, see stdio(3) and setvbuf(3). You should call fflush(3) at appropriate places, in particular before fork(2).

    BTW, the code of your standard libc is free software, probably GNU glibc. Of course it uses syscalls(2). So you should study its source code.

    Read also How to debug small programs

    printf("\nBlock C instructions");
    

    is error-prone. The \n could flush the buffer, and should in practice be used as the last character of printf(3) control format string.