2010-03-11 2 views
2

이 코드는 파이프를 만들고, 두 개의 자식을 생성하고, 죽을 때까지 기다렸다가 다시 시작해야합니다. 그러나 루프 주변의 세 번째 시간에 나는 번호를 입력하라는 메시지를 잃어 버렸고 더 이상 입력 한 번호를 인쇄하지 않습니다. 어떤 아이디어? 엑스 코드 내에서 정상적으로 동작에서 실행했을 때 fprintf가 인쇄 순서를 시작하거나 시작하지 않는 이유는 무엇입니까?

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 

#define WRITE 1 
#define READ 0 

int main (int argc, const char * argv[]) { 

    //Pipe file-descriptor array 
    unsigned int isChildA = 0; 
    int pipeA[2]; 
    int pipeB[2]; 
    int num = 0; 

    while(1){ 


    fprintf(stderr,"Enter an integer: "); 
    scanf("%i", &num); 

    if(num == 0){ 
     fprintf(stderr,"You entered zero, exiting...\n"); 
     exit(0); 
    } 

    //Open Pipes 
    if(pipe(pipeA) < 0){ 
     fprintf(stderr,"Could not create pipe A.\n"); 
     exit(1); 
    } 

    if(pipe(pipeB) < 0){ 
     fprintf(stderr,"Could not create pipe B.\n"); 
     exit(1); 
    } 

    fprintf(stderr,"Value read: %i \n", num); 
    fprintf(stderr,"Parent PID: %i\n", getpid()); 

    pid_t procID = fork(); 

    switch (procID) { 
     case -1: 
      fprintf(stderr,"Fork error, quitting...\n"); 
      exit(1); 
      break; 

     case 0: 
      isChildA = 1; 
      break; 

     default: 
      procID = fork(); 

      if (procID<0) { 
       fprintf(stderr,"Fork error, quitting...\n"); 
       exit(1); 
      } 
      else if(procID == 0){ 
       isChildA = 0; 
      } 

      else { 

       write(pipeA[WRITE], &num, sizeof(int)); 
       close(pipeA[WRITE]); 
       close(pipeA[READ]); 
       close(pipeB[WRITE]); 
       close(pipeB[READ]); 

       pid_t pid; 

       while (pid = waitpid(-1, NULL, 0)) { 
        if (errno == ECHILD) { 
         break; 
        } 
       } 

      } 


      break; 
    } 

    if (procID == 0) { 
     //We're a child, do kid-stuff. 
     ssize_t bytesRead = 0; 
     int response; 

     while (1) { 

      while (bytesRead == 0) { 
       bytesRead = read((isChildA?pipeA[READ]:pipeB[READ]), &response, sizeof(int)); 
      } 
      if (response < 2) { 
       //Kill other child and self 
       fprintf(stderr, "Terminating PROCID: %i\n", getpid()); 
       write((isChildA?pipeB[WRITE]:pipeA[WRITE]), &response, sizeof(int)); 
       close(pipeA[WRITE]); 
       close(pipeA[READ]); 
       close(pipeB[WRITE]); 
       close(pipeB[READ]); 
       return 0; 
      } 
      else if(!(response%2)){ 
       //Even 
       response/=2; 
       fprintf(stderr,"PROCID: %i, VALUE: %i\n", getpid(), response); 
       write((isChildA?pipeB[WRITE]:pipeA[WRITE]), &response, sizeof(int)); 
       bytesRead = 0; 
      } 

      else { 
       //Odd 
       response*=3; 
       response++; 
       fprintf(stderr,"PROCID: %i, VALUE: %i\n", getpid(), response); 
       write((isChildA?pipeB[WRITE]:pipeA[WRITE]), &response, sizeof(int)); 
       bytesRead = 0; 
      } 


     } 
    } 
} 

    return 0; 
} 

, 나는 점점 오전 출력 ... 이상하다

bash-3.00$ ./proj2 
Enter an integer: 101 
Value read: 101 
Parent PID: 9379 
PROCID: 9380, VALUE: 304 
PROCID: 9381, VALUE: 152 
PROCID: 9380, VALUE: 76 
PROCID: 9381, VALUE: 38 
PROCID: 9380, VALUE: 19 
PROCID: 9381, VALUE: 58 
PROCID: 9380, VALUE: 29 
PROCID: 9381, VALUE: 88 
PROCID: 9380, VALUE: 44 
PROCID: 9381, VALUE: 22 
PROCID: 9380, VALUE: 11 
PROCID: 9381, VALUE: 34 
PROCID: 9380, VALUE: 17 
PROCID: 9381, VALUE: 52 
PROCID: 9380, VALUE: 26 
PROCID: 9381, VALUE: 13 
PROCID: 9380, VALUE: 40 
PROCID: 9381, VALUE: 20 
PROCID: 9380, VALUE: 10 
PROCID: 9381, VALUE: 5 
PROCID: 9380, VALUE: 16 
PROCID: 9381, VALUE: 8 
PROCID: 9380, VALUE: 4 
PROCID: 9381, VALUE: 2 
PROCID: 9380, VALUE: 1 
Terminating PROCID: 9381 
Terminating PROCID: 9380 
Enter an integer: 102 
Value read: 102 
Parent PID: 9379 
PROCID: 9386, VALUE: 51 
PROCID: 9387, VALUE: 154 
PROCID: 9386, VALUE: 77 
PROCID: 9387, VALUE: 232 
PROCID: 9386, VALUE: 116 
PROCID: 9387, VALUE: 58 
PROCID: 9386, VALUE: 29 
PROCID: 9387, VALUE: 88 
PROCID: 9386, VALUE: 44 
PROCID: 9387, VALUE: 22 
PROCID: 9386, VALUE: 11 
PROCID: 9387, VALUE: 34 
PROCID: 9386, VALUE: 17 
PROCID: 9387, VALUE: 52 
PROCID: 9386, VALUE: 26 
PROCID: 9387, VALUE: 13 
PROCID: 9386, VALUE: 40 
PROCID: 9387, VALUE: 20 
PROCID: 9386, VALUE: 10 
PROCID: 9387, VALUE: 5 
PROCID: 9386, VALUE: 16 
PROCID: 9387, VALUE: 8 
PROCID: 9386, VALUE: 4 
PROCID: 9387, VALUE: 2 
PROCID: 9386, VALUE: 1 
Terminating PROCID: 9387 
Terminating PROCID: 9386 
Enter an integer: 104 
Value read: 104 
Parent PID: 9379 
Enter an integer: PROCID: 9388, VALUE: 52 
PROCID: 9389, VALUE: 26 
PROCID: 9388, VALUE: 13 
PROCID: 9389, VALUE: 40 
PROCID: 9388, VALUE: 20 
PROCID: 9389, VALUE: 10 
PROCID: 9388, VALUE: 5 
PROCID: 9389, VALUE: 16 
PROCID: 9388, VALUE: 8 
PROCID: 9389, VALUE: 4 
PROCID: 9388, VALUE: 2 
PROCID: 9389, VALUE: 1 
Terminating PROCID: 9388 
Terminating PROCID: 9389 
105 
Value read: 105 
Parent PID: 9379 
Enter an integer: PROCID: 9395, VALUE: 316 
PROCID: 9396, VALUE: 158 
PROCID: 9395, VALUE: 79 
PROCID: 9396, VALUE: 238 
PROCID: 9395, VALUE: 119 
PROCID: 9396, VALUE: 358 
PROCID: 9395, VALUE: 179 
PROCID: 9396, VALUE: 538 
PROCID: 9395, VALUE: 269 
PROCID: 9396, VALUE: 808 
PROCID: 9395, VALUE: 404 
PROCID: 9396, VALUE: 202 
PROCID: 9395, VALUE: 101 
PROCID: 9396, VALUE: 304 
PROCID: 9395, VALUE: 152 
PROCID: 9396, VALUE: 76 
PROCID: 9395, VALUE: 38 
PROCID: 9396, VALUE: 19 
PROCID: 9395, VALUE: 58 
PROCID: 9396, VALUE: 29 
PROCID: 9395, VALUE: 88 
PROCID: 9396, VALUE: 44 
PROCID: 9395, VALUE: 22 
PROCID: 9396, VALUE: 11 
PROCID: 9395, VALUE: 34 
PROCID: 9396, VALUE: 17 
PROCID: 9395, VALUE: 52 
PROCID: 9396, VALUE: 26 
PROCID: 9395, VALUE: 13 
PROCID: 9396, VALUE: 40 
PROCID: 9395, VALUE: 20 
PROCID: 9396, VALUE: 10 
PROCID: 9395, VALUE: 5 
PROCID: 9396, VALUE: 16 
PROCID: 9395, VALUE: 8 
PROCID: 9396, VALUE: 4 
PROCID: 9395, VALUE: 2 
PROCID: 9396, VALUE: 1 
Terminating PROCID: 9395 
Terminating PROCID: 9396 
105 
Value read: 105 
Parent PID: 9379 
Enter an integer: PROCID: 9397, VALUE: 316 
PROCID: 9398, VALUE: 158 
PROCID: 9397, VALUE: 79 
PROCID: 9398, VALUE: 238 
PROCID: 9397, VALUE: 119 
PROCID: 9398, VALUE: 358 
PROCID: 9397, VALUE: 179 
PROCID: 9398, VALUE: 538 
PROCID: 9397, VALUE: 269 
PROCID: 9398, VALUE: 808 
PROCID: 9397, VALUE: 404 
PROCID: 9398, VALUE: 202 
PROCID: 9397, VALUE: 101 
PROCID: 9398, VALUE: 304 
PROCID: 9397, VALUE: 152 
PROCID: 9398, VALUE: 76 
PROCID: 9397, VALUE: 38 
PROCID: 9398, VALUE: 19 
PROCID: 9397, VALUE: 58 
PROCID: 9398, VALUE: 29 
PROCID: 9397, VALUE: 88 
PROCID: 9398, VALUE: 44 
PROCID: 9397, VALUE: 22 
PROCID: 9398, VALUE: 11 
PROCID: 9397, VALUE: 34 
PROCID: 9398, VALUE: 17 
PROCID: 9397, VALUE: 52 
PROCID: 9398, VALUE: 26 
PROCID: 9397, VALUE: 13 
PROCID: 9398, VALUE: 40 
PROCID: 9397, VALUE: 20 
PROCID: 9398, VALUE: 10 
PROCID: 9397, VALUE: 5 
PROCID: 9398, VALUE: 16 
PROCID: 9397, VALUE: 8 
PROCID: 9398, VALUE: 4 
PROCID: 9397, VALUE: 2 
PROCID: 9398, VALUE: 1 
Terminating PROCID: 9397 
Terminating PROCID: 9398 
106 
Value read: 106 
Parent PID: 9379 
Enter an integer: PROCID: 9399, VALUE: 53 
PROCID: 9400, VALUE: 160 
PROCID: 9399, VALUE: 80 
PROCID: 9400, VALUE: 40 
PROCID: 9399, VALUE: 20 
PROCID: 9400, VALUE: 10 
PROCID: 9399, VALUE: 5 
PROCID: 9400, VALUE: 16 
PROCID: 9399, VALUE: 8 
PROCID: 9400, VALUE: 4 
PROCID: 9399, VALUE: 2 
PROCID: 9400, VALUE: 1 
Terminating PROCID: 9399 
Terminating PROCID: 9400 
^C 

또 다른 일이다. 그러나 Solaris 또는 OSX에서 bash를 실행하면 작동합니다.

답변

2

waitpid()를 교체하고 대신이 시도 : 대답에 대한

/* 
while (pid = waitpid(-1, NULL, 0)) 
{ 
    if (errno == ECHILD) 
    { 
     break; 
    } 
} 
*/ 

while (1) 
{ 
    if ((pid = waitpid(-1, NULL, 0)) == -1) 
    { 
     if (errno == ECHILD) 
      break; 
    } 
    else 
     printf("I am %d and I am reaped %d\n", getpid(), pid); 
} 
+0

감사합니다. 그게 효과가 있었어! 그러나 당신의 솔루션이 내가 가진 것과는 다른 점을 조금 설명 할 수 있습니까? –

+0

waitpid()가 성공하면 errno를 재설정하지 않으므로 첫 번째 ECHILD 이후 오류 코드가 그대로 유지됩니다. 다음 반복에서 waitpid()가 자식을 찾았음에도 루프는 ECHILD 테스트에서 종료되었고 두 번째 자식을 포착하지 않았습니다. 그것은 인쇄 순서를 어지럽 혔습니다. – Duck

0

인쇄 된 문자열 끝에 줄 바꿈이없는 fprintf 다음에 fflush를 호출하십시오.

+0

감사합니다,하지만 난 그것을 시도했습니다. stderr가 stdout처럼 버퍼링되지 않아 fflush가 필요하지 않다는 것이 내 이해입니다. –

+0

맞습니다. stderr은 버퍼링되지 않습니다. – tomlogic

관련 문제