Мультипроцесс и выход - PullRequest
       14

Мультипроцесс и выход

0 голосов
/ 17 апреля 2020

Я делаю домашнее задание о мультиобработке.

В этом домашнем задании нас просят использовать функцию fork () для разветвления другого процесса от одного родительского процесса. Затем мы делаем ту же симуляцию на другом дочернем процессе. Проблема связана со спортивной игрой. Программа должна иметь возможность имитировать функцию группировки для разных команд.

Теперь я сосредоточился на первой части, которая является тестовым режимом, и у меня возникли некоторые проблемы.

Я получил вывод вроде

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

В этой программе я разветвляю два процесса, и на выходе возникает проблема, что дочерний элемент 1 прерывается, а затем дочерний элемент 2 печатает свое сообщение. Следовательно, "ing" отделяется одним фрагментом вывода Child2.

Пример вывода должен быть похож на


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


Вот мой код.

#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;
}







Нужно ли выполнять какую-то работу с помощью Lock? Спасибо !!!

1 Ответ

0 голосов
/ 17 апреля 2020

Все процессы fork ed записываются в stdout асинхронно. Там нет никаких гарантий о порядке. Вызов setlinebuf (эквивалент setvbuf(stream, NULL, _IOLBF, 0)) один раз при запуске программы и fflush после каждого printf должен помочь , но не обязательно решит вашу проблему во всех случаях.

Указание размера буфера больше ожидаемой самой длинной строки при вызове setvbuf также поможет:

char buffer[16000]; // 16000 is the buffer size in bytes
...
int main(int argc, char **argv)
{
    setvbuf(stdout, buffer, _IOLBF, sizeof buffer);
...
...