当两个子流程通过管道与父流程进行通信时,一个子流程会阻止另一个子流程(One sub

编程入门 行业动态 更新时间:2024-10-28 14:30:41
当两个子流程通过管道与父流程进行通信时,一个子流程会阻止另一个子流程(One sub-process blocks another sub-process when both communicates with a parent process through a pipe)

我的流程编程老师让我在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); }

它似乎是正确的,但它无法正常工作。 当第二个孩子完成计算其数字范围(从125000到249999)时,它会阻止第一个孩子并且第一个孩子停止。

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

[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写入管道并从父母读取,以及为什么第二个孩子完成阻止第一个孩子。

问候。

my Process Programming teacher made me write a program on C that creates four childs and makes them calculate the first, second, third and fourth quarters respectively, of a range of numbers, giving the parent all the prime numbers on them.

I coded correctly the first child quarter, but when I added the second child the program's behavior comes uncontrolable. My teacher and I have spent about 2 hours looking depth in the code and we've not found the problem.

The code is this as I have it right now:

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

It appears to be correct, but it doesn't work properly. When the second child finishes calculating its range of numbers (From 125000 to 249999) it blocks the first child and the first child stops.

Then the program enters in an infinite loop of reading and printing the pipe's content And it looks like this:

[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

And so. So we ask HOW 250000 could have been written to the pipe and read from the parent, and why the second child finishing blocks the first child.

Greetings.

最满意答案

在第67行,你的代码突破了第二个switch语句(第45行)。 执行从第77行恢复。因此子进程2试图关闭(fd2 [1])两次。 子进程2正在执行以父进程为目标的代码。

您可以尝试用第67行替换

exit(0);

at line 67 your code breaks out of the second switch statement (line 45). Execution resumes at line 77. So child process 2 is trying to close ( fd2[1] ) twice. Child process 2 is executing code targetted at parent process.

You could try replacing line 67 with

exit(0);

更多推荐

本文发布于:2023-07-29 23:58:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1320787.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:流程   个子   管道   通信

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!