2014-10-10 5 views
0

내 프로세스 프로그래밍 선생님이 네 개의 하위 항목을 생성하고 첫 번째, 두 번째, 세 번째 및 네 번째 분기를 계산하는 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이 파이프에 쓰여지고 부모로부터 읽힐 수 있었고 두 번째 아이가 첫 번째 아이를 막는 이유를 묻습니다.

인사말.

답변

0

라인 67에서 코드는 두 번째 switch 명령문 (45 행)에서 나옵니다. 실행은 77 행에서 다시 시작됩니다. 따라서 하위 프로세스 2가 두 번 (fd2 [1])을 닫으려고합니다. 하위 프로세스 2가 상위 프로세스에서 대상 코드를 실행 중입니다. 당신은

exit(0); 
+0

에 맞춰 67을 교체 시도 할 수

당신이 솔루션이 제대로 작동 감사드립니다. 어쨌든 250000이 어디에 나타나는지 알고 싶습니다. –

+0

boolean 함수를 작성 하시겠습니까? isPrime ( –

+0

) 부울 함수 isPrime (long candidatePrime, long testDenominator)을 작성할 것을 제안합니다. 모든 숫자가 아닌 소수의리스트를 사용하는 것이 가장 좋습니다. ansi c에서 길다. –

관련 문제