多进程和输出
Posted
技术标签:
【中文标题】多进程和输出【英文标题】:The multi-process and output 【发布时间】:2020-07-30 12:51:51 【问题描述】:我正在做关于多处理的作业。
在这个作业中,我们被要求使用 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
在这个程序中,我 fork 两个进程,输出有一个 Child 1 中断的问题,然后 Child2 打印它的消息。因此,“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】:所有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);
...
【讨论】:
以上是关于多进程和输出的主要内容,如果未能解决你的问题,请参考以下文章