Q:

The multi-process and output

I am doing a homework about multi-processing.
In this homework we are asked to use fork() function to fork different process from one parent process. Then we do same simulation on different child process. The problem is related to sports game. The program should be able to simulate the grouping function for different teams.
Now I am focusing on the first part that is test mode and I meet some problems.
I got the output like
Parent, pid 57361 : 2 children T Mode 
Child 1 , pid 57362 : teams for pot 0 are : Liverpool Arsenal Barcelona ManCity Juventus Bayern Paris Zenit 
Child 1 , pid 57362 : teams for pot 1 are : RealMadrid Atletico Chelsea Dortmund Napoli Shakhtar Tottenham Ajax 
Child 1 , pid 57362 : teams for pot 2 are : Benfica Lyon Leverkusen Salzburg Olympiacos Brugge Valencia Internazionale 
Child 1 , pid 57362 : teams for pot 3 are : Zagreb Lokomotiv Genk Galatasaray Leipzig SlaviaPraha Atalanta Lille 
Child 1 , pid 57362 : Teams for group A are RealMadrid Brugge Galatasaray Paris 
Child 1 , pid 57362 : pots for group A are 2 3 4 1 
Child 1 , pid 57362 : country for group A are Spain Belgium Turkey France 
Child 1 , pid 57362 : Teams for group B are Lille Olympiacos Tottenham Bayern 
Child 1 , pid 57362 : pots for group B are 4 3 2 1 
Child 1 , pid 57362 : country for group B are France Greece England Germany 
Child 1 , pid 57362 : Teams for group C are ManCity Valencia Atalanta Shakhtar 
Child 1 , pid 57362 : pots for group C are 1 3 4 2 
Child 2 , pid 57363 : teams for pot 0 are : Liverpool Arsenal Barcelona ManCity Juventus Bayern Paris Zenit 
Child 1 , pid 57362 : country for group C are England Spain Italy Ukraine 
Child 2 , pid 57363 : teams for pot 1 are : RealMadrid Atletico Chelsea Dortmund Napoli Shakhtar Tottenham Ajax 
Child 2 , pid 57363 : teams for pot 2 are : Benfica Lyon Leverkusen Salzburg Olympiacos Brugge Valencia Internazionale 
Child 2 , pid 57363 : teams for pot 3 are : Zagreb Lokomotiv Genk Galatasaray Leipzig SlaviaPraha Atalanta Lille 
Child 1 , pid 57362 : Teams for group D are Juventus Leverkusen Lokomotiv Atletico 
Child 2 , pid 57363 : Teams for group A are RealMadrid Brugge Galatasaray Paris 
Child 1 , pid 57362 : pots for group D are 1 3 4 2 
Child 2 , pid 57363 : pots for group A are 2 3 4 1 
Child 1 , pid 57362 : country for group D are Italy Germany Russia Spain 
Child 2 , pid 57363 : country for group A are Spain Belgium Turkey France 
Child 1 , pid 57362 : Teams for group E are Genk Napoli Liverpool Salzburg 
Child 1 , pid 57362 : pots for group E are 4 2 1 3 
Child 2 , pid 57363 : Teams for group B are Lille Olympiacos Tottenham Bayern 
Child 1 , pid 57362 : country for group E are Belgium Italy England Austria 
Child 1 , pid 57362 : Teams for group F are Barcelona Internazionale SlaviaPraha Dortmund 
Child 2 , pid 57363 : pots for group B are 4 3 2 1 
Child 1 , pid 57362 : pots for group F are 1 3 4 2 
Child 1 , pid 57362 : country for group F are Spain Italy Czech Germany 
Child 2 , pid 57363 : country for group B are France Greece England Germany 
Child 1 , pid 57362 : Teams for group G are Leipzig Lyon Zenit Chelsea 
Child 2 , pid 57363 : Teams for group C are ManCity Valencia Atalanta Shakhtar 
Child 1 , pid 57362 : pots for group G are 4 3 1 2 
Child 2 , pid 57363 : pots for group C are 1 3 4 2 
Child 1 , pid 57362 : country for group G are Germany France Russia England 
Child 2 , pid 57363 : country for group C are England Spain Italy Ukraine 
Child 1 , pid 57362 : Teams for group H are Arsenal Benfica Zagreb Ajax 
Child 2 , pid 57363 : Teams for group D are Juventus Leverkusen Lokomotiv Atletico 
Child 1 , pid 57362 : pots for group H are 1 3 4 2 
Child 2 , pid 57363 : pots for group D are 1 3 4 2 
Child 1 , pid 57362 : country for group H are England Portugal Croatia Netherlands 
Child 2 , pid 57363 : country for group D are Italy Germany Russia Spain 
Child 1, pid 57362 : Valid GroupiChild 2 , pid 57363 : Teams for group E are Genk Napoli Liverpool Salzburg 
ng
Child 2 , pid 57363 : pots for group E are 4 2 1 3 
Child 2 , pid 57363 : country for group E are Belgium Italy England Austria 
Child 2 , pid 57363 : Teams for group F are Barcelona Internazionale SlaviaPraha Dortmund 
Child 2 , pid 57363 : pots for group F are 1 3 4 2 
Child 2 , pid 57363 : country for group F are Spain Italy Czech Germany 
Child 2 , pid 57363 : Teams for group G are Leipzig Lyon Zenit Chelsea 
Child 2 , pid 57363 : pots for group G are 4 3 1 2 
Child 2 , pid 57363 : country for group G are Germany France Russia England 
Child 2 , pid 57363 : Teams for group H are Arsenal Benfica Zagreb Ajax 
Child 2 , pid 57363 : pots for group H are 1 3 4 2 
Child 2 , pid 57363 : country for group H are England Portugal Croatia Netherlands 
Child 2, pid 57363 : Valid Grouping

In this program, I fork two processes and the output has a problem that Child 1 interupts and then the Child2 prints its message. Therefore, the "ing" is seperated by one piece of output of Child2.
The sample output should be like

Parent, pid 12352: 2 children, test mode
Child 1, pid 12353: teams for pot 1 are Liverpool Arsenal Barcelona ManCity Juventus Bayern Paris
Zenit
Child 1, pid 12353: teams for pot 2 are RealMadrid Atletico Chelsea Dortmund Napoli Shakhtar
Tottenham Ajax
Child 1, pid 12353: teams for pot 3 are Benfica Lyon Leverkusen Salzburg Olympiacos Brugge
Valencia Internazionale
Child 2, pid 12355: teams for pot 1 are Liverpool Arsenal Barcelona ManCity Juventus Bayern Paris
Zenit
Child 2, pid 12355: teams for pot 2 are RealMadrid Atletico Chelsea Dortmund Napoli Shakhtar
Tottenham Ajax
Child 2, pid 12355: teams for pot 3 are Benfica Lyon Leverkusen Salzburg Olympiacos Brugge
Valencia Internazionale
Child 2, pid 12355: teams for pot 4 are Zagreb Lokomotiv Genk Galatasaray Leipzig SlaviaPraha
Atalanta Lille
Child 2, pid 12355: teams for group A are RealMadrid Brugge Galatasaray Paris
Child 1, pid 12353: teams for pot 4 are Zagreb Lokomotiv Genk Galatasaray Leipzig SlaviaPraha
Atalanta Lille
Child 1, pid 12353: teams for group A are RealMadrid Brugge Galatasaray Paris
Child 1, pid 12353: pots for group A are 2 3 4 1
Child 1, pid 12353: countries for group A are Spain Belgium Turkey France
Child 1, pid 12353: teams for group B are Lille Olympiacos Tottenham Bayern
Child 1, pid 12353: pots for group B are 4 3 2 1
Child 1, pid 12353: countries for group B are France Greece England Germany
. . .
Child 2, pid 12355: countries for group F are Spain Italy Czech Germany
Child 2, pid 12355: teams for group G are Leipzig Lyon Zenit Chelsea
Child 2, pid 12355: pots for group G are 4 3 1 2
Child 1, pid 12353: pots for group H are 1 3 4 2
Child 1, pid 12353: countries for group H are Austria Portugal Croatia Netherlands
Child 1, pid 12353: Valid grouping
Child 2, pid 12355: countries for group G are Germany France Russia England
Child 2, pid 12355: teams for group H are Arsenal Benfica Zagreb Ajax
Child 2, pid 12355: pots for group H are 1 3 4 2
Child 2, pid 12355: countries for group H are Austria Portugal Croatia Netherlands
Child 2, pid 12355: Valid grouping

Here is my code.
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <errno.h>

#define LENGTH sizeof(TEAM)/sizeof(TEAM[0])
#define GROUPNUM sizeof(GROUP)/sizeof(GROUP[0])

char *TEAM[] = {"Ajax", "Atalanta", "Atletico", "Barcelona", "Bayern",
                "Benfica", "Brugge", "Chelsea", "Crvenazvezda", "Dortmund", "Galatasaray",
                "Genk", "Internazionale", "Juventus", "Leipzig", "Leverkusen", "Liverpool",
                "Lokomotiv", "Lille", "Lyon", "ManCity", "Napoli", "Olympiacos", "Paris",
                "RealMadrid", "Salzburg", "Shakhtar", "SlaviaPraha", "Tottenham", "Valencia",
                "Zagreb", "Zenit", "Arsenal"};

char *COUNTRY[] = {"Netherlands", "Italy", "Spain", "Spain", "Germany",
                   "Portugal", "Belgium", "England", "Serbia", "Germany", "Turkey", "Belgium",
                   "Italy", "Italy", "Germany", "Germany", "England", "Russia", "France",
                   "France", "England", "Italy", "Greece", "France", "Spain", "Austria",
                   "Ukraine", "Czech", "England", "Spain", "Croatia", "Russia", "England"};

char *GROUP[] ={"group A", "group B", "group C", "group D", "group E", "group F", "group G", "group H"};

const char* getCountry(char * team){
    int i;
    char* str;
    for(i=0;i<LENGTH;i++){
        str = TEAM[i];
        if ( ( strcmp(team, str) ) == 0){
            break;
        }
    }

    return COUNTRY[i];
}

int canTheyMeet(char* str1, char* str2){
    str1 = getCountry(str1);
    str2 = getCountry(str2);
    int flag=1;
    if ( (strcmp(str1, str2)) == 0 )
        flag = 0;
    if ( (strcmp(str1, "Ukraine")) == 0 && (strcmp(str2, "Russia")) == 0 )
        flag = 0;

    if ( (strcmp(str2, "Ukraine")) == 0 && (strcmp(str1, "Russia")) == 0 )
        flag = 0;

    return flag;
}

// Return Country and It cannot be changed

int whichPot(char * team, char *** result){
    int i,j,flag=0;
    for(i=0;i<4;i++){
        for(j=0;j<8;j++){
            char *str = result[i][j];
            if( (strcmp(team, str)) == 0 ){
                flag=1;
                break;
            }
        }
        if(flag==1)
            break;
    }

    return i+1;
}

int isGroupValid(char ** group, char *** result){
    int i,j;
    int flag = 1;
    for(i=0;i<3;i++){
        for(j=i+1;j<4;j++){
            char *str1 = group[i];
            char *str2 = group[j];
            if(!canTheyMeet(str1, str2) || whichPot(str1, result) == whichPot(str2, result)){
                flag=0;
                break;
            }
        }
    }
    return flag;
}

// only for test mode, we generate the Group for each teams
char *** generateGroup(char** argv, int length){
    int m;
    char *** result;
    result = (char ***)malloc(sizeof(char**)*8);
    for(m=0;m<8;m++){
        result[m] = (char**)malloc(sizeof(char*)*4);
    }
    int k,j;
    int i=35;
    for(k=0;k<8;k++){
        for(j=0;j<4;j++){
            char* string = argv[i + j];

            result[k][j] = string;
        }
        i+=4;
    }

    return result;

}

// set Teams to different pots
// The pots are three dimensional Array
char *** getTeams(char** argv, int length){
    int m;
    char *** result;
    result = (char ***)malloc(sizeof(char**)*4);
    for (m=0;m<4;m++){
        result[m] = (char**)malloc(sizeof(char*)*8);
    }

    int i=3;
    int j=0;
    int k=0;
     //Iterative get all the information of setmode
    for(; k<4; k++) {
        // four pots

            for (; j < 8; j ++) {
                // get string
                char *string = argv[i + j];
                result[k][j] = string;
            }
            i+=8;
            j=0;
    }
    return result;
}

void TestMode(char ** argv, int length, int id){
    char *** teamPot = getTeams(argv, length);
    char *** groups = generateGroup(argv, length);
    int i,j,validBit=1;
    for(i=0;i<4;i++){
        printf("Child %d , pid %d : teams for pot %d are : ", id, getpid(), i);
        for(j=0;j<8;j++){
            printf("%s ", teamPot[i][j]);
        }
        printf("\n");
    }

    for(i=0;i<8;i++){
        printf("Child %d , pid %d : Teams for %s are ", id, getpid(), GROUP[i]);
        for(j=0;j<4;j++){
            printf("%s ", groups[i][j]);
        }
        printf("\n");

        printf("Child %d , pid %d : pots for %s are ", id, getpid() ,GROUP[i]);
        for(j=0;j<4;j++){
            printf("%d ", whichPot(groups[i][j], teamPot));
        }
        printf("\n");

        printf("Child %d , pid %d : country for %s are ", id, getpid() ,GROUP[i]);
        for(j=0;j<4;j++){
            printf("%s ", getCountry(groups[i][j]));
        }
        printf("\n");
        char ** group = groups[i];
        if(!isGroupValid(group, teamPot)){
            printf("Child %d, pid %d : InValid Grouping\n" , id, getpid());
            validBit=0;
            break;
        }
    }
    if(validBit)
        printf("Child %d, pid %d : Valid Grouping\n", id, getpid());
    free(teamPot);
    free(groups);

}

void GenerateMode(){}

int main(int argc, char **argv) {
    printf("Hello, World! %d\n", GROUPNUM);

    int k=0;
    int status=0;

    // get number of child process
    int numOfChild = 2;
    // The parent Id
    pid_t ppid = getpid();

    printf("Parent, pid %d : %d children %s Mode \n", ppid, numOfChild, argv[2]);
    pid_t pid;

    for(k=0;k<numOfChild;k++){
        if(fork() == 0){
            if ((strcmp(argv[2], "T") == 0)){
                TestMode(argv, argc, k+1);
                exit(0);
            }else if ((strcmp(argv[2], "G")) == 0){
                GenerateMode();
            }

        }
    }
    for(k=0;k<numOfChild;k++){
        wait(NULL);
    }

    return 0;
}

Do I need to do some jobs with Lock?
Thanks!!!

A:

All forked processes are writing to stdout asynchronously.  There are no guarantees about order.  Calling setlinebuf (equivalent to setvbuf(stream, NULL, _IOLBF, 0)) once at start of the program and fflush after each printf should help, but will not necessarily solve your problem in all cases.
Specifying a buffer size larger than your anticipated longest line when calling setvbuf will also help:
char buffer[16000]; // 16000 is the buffer size in bytes
...
int main(int argc, char **argv)
{
    setvbuf(stdout, buffer, _IOLBF, sizeof buffer);
...

