gpt4 book ai didi

c - 当两个子进程都通过管道与父进程通信时,一个子进程会阻塞另一个子进程

转载 作者:行者123 更新时间:2023-11-30 17:27:44 27 4
gpt4 key购买 nike

我的流程编程老师让我用 C 语言编写一个程序,创建四个子项,并让它们分别计算一系列数字的第一、第二、第三和第四个季度,并为父项提供所有素数。

我对第一个子季度的编码正确,但是当我添加第二个子季度时,程序的行为变得无法控制。我和我的老师花了大约 2 个小时深入研究代码,但没有发现问题。

代码是这样的,因为我现在拥有它:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main(){

unsigned long long a=500000,b,c; // not used yet -> d,e,i;
pid_t pid1;
unsigned long long fin = 0; //This is used in each child to write if it has finished the prime number calculation.
unsigned long long fin1 = 0, fin2 = 0; //This is used on the parent to check if a child has finished.
int primo = 0; //This is used to know if a number is a prime number.
int fd1[2]; //Pipe which communicates the parent with the first child.
int fd2[2]; //Pipe which communicates the parent with the second child.
// int fd3[2]; //Not used yet
// int fd4[4]; //Not used yet
pipe(fd1); //First child pipe
pipe(fd2); //Second child pipe
// pipe(fd3); //Not used yet
// pipe(fd4); //Not used yet
pid1 = fork(); //Creating first child
switch (pid1){
case -1: //Error
printf("Error creating child.");
exit(-1);
case 0: //First child
close(fd1[0]); //Input close
for(b=100;b<(a/4);b++){ //
for(i=2;i<b/2;i++){ // These loops check each number from 100 to 125000
if(b%i==0){ // and if it is NOT a prime number, it breaks and tries
primo=0; // to check the next number.
break; //
} //
primo=1; //
}
if(primo==1){ //If it IS a prime number, it's written on the pipe
write(fd1[1], &b, sizeof(b)); //and sent to the parent.
}
}
fin=1; //The child sets it has finished calculating and writes it in the pipe to tell his parent.
write(fd1[1], &fin, sizeof(fin));
close(fd1[1]); //Output closing
break; //First child ends
default: //Parent

pid1 = fork(); //Creating second child
switch (pid1) {

case -1: //error
printf("Error");
exit(-1);
case 0: //Sencond child
close(fd2[0]); //This behavior is EXACTLY equals to the first child behavior
for(c=(a/4);c<(a/2);c++){ //
q for(i=2;i<c/2;i++){ //
if(c%i==0){ //
primo=0; //
break; //
} //
primo=1; //
} //
if(primo==1){ //
write(fd2[1], &c, sizeof(c)); //
} //
} //
fin=1; //
write(fd2[1], &fin, sizeof(fin)); //
close(fd2[1]); //
break;
default: //Parent
//HERE WOULD COME THE CODE FOR THIRD AND FOURTH CHILDS.
break;



} //second child switch close

//Parent reads answers from childs
close(fd1[1]); //First child output closing
close(fd2[1]); //Second child output closing
for(;;){ //Infinite loop
if(fin1==0){ //If first child HAS NOT finished (As it sends a 1 if it does)
read(fd1[0], &b, sizeof(b)); //Read the prime number
if(b==1){ //If it is a 1, then the child has finished.
fin1=1; //We set the first child has finished
close(fd1[0]); //First child input closing
}else{
printf("%llu es primo\n", b); //Otherwise it is a prime number, then it's printed to console.
}
}
if(fin2==0){ //Same behavior as with first child
read(fd2[0], &c, sizeof(c));
if(c==1){
fin2=1;
close(fd2[0]);
}else{
printf("%llu es primo\n", c);
}
}
if(fin1==1&&fin2==1){ //If both childs have finished, then we exit.
exit(0);
}
}
break;

}
exit(0);
}

它看起来是正确的,但它不能正常工作。当第二个 child 完成计算其数字范围(从 125000 到 249999)时,它会阻止第一个 child ,第一个 child 会停止。

然后程序进入读取和打印管道内容的无限循环它看起来像这样:

[first child last calculated number] es primo
250000 es primo
[first child last calculated number] es primo
250000 es primo
[first child last calculated number] es primo
250000 es primo
[first child last calculated number] es primo
250000 es primo

所以。因此,我们问如何将 250000 写入管道并从父级读取,以及为什么第二个子级完成会阻塞第一个子级。

问候。

最佳答案

在第 67 行,您的代码脱离了第二个 switch 语句(第 45 行)。执行在第 77 行恢复。因此子进程 2 尝试关闭 ( fd2[1] ) 两次。子进程 2 正在执行针对父进程的代码。

您可以尝试将第 67 行替换为

exit(0);

关于c - 当两个子进程都通过管道与父进程通信时,一个子进程会阻塞另一个子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26297661/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com