【发布时间】:2022-02-06 16:28:50
【问题描述】:
我想要一个父母和孩子互相交谈的程序。 所以输出将是:
- p:值
- c: 值
- p: 单词
- c: 字
等等……
下面是一个代码示例,其中输出首先与父级对话,然后在子级对话。 如何更正代码?
for(int i=0; i<N; i++){
pid=fork();
if(pid==-1){
perror("fork\n");
exit(EXIT_FAILURE);
}
else if(pid==0){
srand(time(NULL));
int c;
read(fd[i][0], &c, 1);
printf("c: value: %d\n", c);
char word[c];
read(fd[i][0],&word, sizeof(word));
printf("c: word: %s\n", word);
int sum;
sum=c*i;
write(fd[i][1], &sum, sizeof(int));
printf("c: sended %d\n", sum);
int flag=0;
printf("flag :%d\n", flag);
read(fd[i][0], &flag, sizeof(int));
printf("c: flag= %d ->exit\n", flag);
exit(1);
}else{
int c;
c=rand()%100+1;
write(fd[i][1], &c, sizeof(int));
printf("p: value: %d\n", c);
char word[c];
write(fd[i][1], &word, sizeof(word));
printf("p: word: %s\n", word);
int sum;
read(fd[i][0], &sum, sizeof(int));
printf("p: sum is: %d\n", sum);
int flag=1;
write(fd[i][1], &flag, sizeof(int));
printf("par: flag exit %d\n", flag);
wait(NULL);
}
}
【问题讨论】:
-
首先,您需要在分叉之前为随机数生成器播种。在子进程中调用
srand不会影响父进程在调用rand时。其次,您应该始终检查read和write返回的内容。第三,您只将 一个 字节读入c,但c是多字节类型(int通常是四个字节)。这意味着c中的大多数位将是indeterminate(将它们视为垃圾)。这也意味着父进程写入的三个字节不会在第一次read调用中被读取,而是稍后用于错误的数据。 -
我已经纠正了这些错误,但没有改变任何东西。输出首先让父母“交谈”,然后是孩子,所以他们不交换任何信息。
-
请记住,管道只有一种方式。如果您需要发送和接收,则需要 两个 管道。
-
为此我有一个二维数组,值 0->read, 1->write
-
不,这是不对的,索引
0和1是同一管道的一部分。您需要两个独立的管道,它们由对pipe的两个不同调用创建。喜欢int pipes[2][2]; pipe(pipes[0]); pipe(pipes[1]);然后父母可以使用例如pipes[0][0]阅读和pipes[1][1]写作,而孩子使用pipes[1][0]和pipes[0][1]。
标签: c process synchronization pipe parent-child