我正在做一项关于多重处理的作业。
在这个家庭作业中,我们被要求使用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
在这个程序中,我分叉了两个进程,输出出现了Child 1中断,然后Child 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 Groupingn" , id, getpid());
validBit=0;
break;
}
}
if(validBit)
printf("Child %d, pid %d : Valid Groupingn", id, getpid());
free(teamPot);
free(groups);
}
void GenerateMode(){}
int main(int argc, char **argv) {
printf("Hello, World! %dn", 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;
}
我需要用洛克做一些工作吗?谢谢
所有fork
ed进程都在异步写入stdout
。秩序无法保证。在程序开始时调用setlinebuf
(相当于setvbuf(stream, NULL, _IOLBF, 0)
(一次,在每个printf
之后调用fflush
应该有帮助,但不一定在所有情况下都能解决您的问题。
在调用setvbuf
时指定一个大于预期最长行的缓冲区大小也会有所帮助:
char buffer[16000]; // 16000 is the buffer size in bytes
...
int main(int argc, char **argv)
{
setvbuf(stdout, buffer, _IOLBF, sizeof buffer);
...