2016-11-13 1 views
0

부모 프로세스가 4 개의 정수 변수 (a, b, c 및 x)에 대한 사용자 입력을 받아서 하위 프로세스로 파이프 처리하려고합니다. 자식 프로세스는 ax^2 + bx + c를 평가하고 결과 r을 부모에게 파이프합니다.C에서 파이프를 통한 부모 - 자식 통신

내가 지금 가지고있는 코드를 사용하면 결과는 1이됩니다. print 서술문의 동작은 x가 읽히고 있다고 생각하게 만듭니다. 그러나 x * x를 r으로하려고해도, 올바른 솔루션을 얻지 못합니다. 나는 무엇을 잘못 할 수 있 었는가?

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/wait.h> 
#define PIPE_INPUT 0 
#define PIPE_OUTPUT 1 
#define INDENT 20 

void testError(int err, const char * str){ 
if (err < 0){ 
    perror(str); 
exit(EXIT_FAILURE); 
} 
} 

int main(){ 

int fd_toChild[2]; 
int fd_toParent[2]; 

int buff[20]; 

pid_t pid; 

testError(pipe(fd_toChild), "pipe"); 
testError(pipe(fd_toParent), "pipe"); 
testError(pid = fork(), "fork"); 

int a; 
int b; 
int c; 
int x; 
int r; 

if (pid > 0){  
    // this is the parent 


    int status; 

    while(1){ 

     close(fd_toChild[PIPE_INPUT]); 
     close(fd_toParent[PIPE_OUTPUT]); 


     printf("This program will evaluate a polynomial a(x^2) + bx + c. \n"); 
     printf("Please input an integer value for a: "); 
     scanf("%d", &a); 
     write(fd_toChild[PIPE_OUTPUT], &a, sizeof(a)); 

     printf("Parent writes value %d to a \n", a); 
     printf("Please input an integer value for b: "); 
     scanf("%d", &b); 
     write(fd_toChild[PIPE_OUTPUT], &b, sizeof(b)); 
     printf("Parent writes value %d to b \n", b); 

     printf("Please input an integer value for c: "); 
     scanf("%d", &c); 
     write(fd_toChild[PIPE_OUTPUT], &c, sizeof(c)); 
     printf("Parent writes value %d to c \n", c); 

     printf("Please input an integer value for x: "); 
     scanf("%d", &x); 
     write(fd_toChild[PIPE_OUTPUT], &x, sizeof(x)); 
     printf("Parent writes value %d to x \n", x); 

     close(fd_toChild[PIPE_OUTPUT]); 
     close(fd_toParent[PIPE_INPUT]); 

     read(fd_toParent[PIPE_INPUT], buff, sizeof(r)); 

     pid = wait(&status); 

     fprintf(stdout, "Parent received back the result %d.\n", r); 
     printf("The polynomial evaluates to %d \n", r); 

     close(fd_toParent[PIPE_OUTPUT]); 

     break; 
    } 
} 

else{ 
    // this is child 

    close(fd_toChild[PIPE_OUTPUT]); 
    close(fd_toParent[PIPE_INPUT]); 

    while(1){ 
     close(fd_toChild[PIPE_OUTPUT]); 
     close(fd_toParent[PIPE_INPUT]); 

     read(fd_toChild[PIPE_INPUT], buff, sizeof(a)); 
     printf("Child reads value %d from a \n", a); 

     read(fd_toChild[PIPE_INPUT], buff, sizeof(b)); 
     printf("Child reads value %d from b \n", b); 

     read(fd_toChild[PIPE_INPUT], buff, sizeof(c)); 
     printf("Child reads value %d from c \n", c); 

     read(fd_toChild[PIPE_INPUT], buff, sizeof(x)); 
     printf("Child reads value %d from x \n", x); r = a * x * x + b * x + c; 
     printf("x is %d", x); printf("r is %d", r); 

     write(fd_toParent[PIPE_OUTPUT], buff, sizeof(r)); 
     fprintf(stdout, "%*sChild is all done\n", INDENT, ""); 
     close(fd_toChild[PIPE_INPUT]); 

    } 
} 
return EXIT_SUCCESS; 
} 
+0

:

나는 코드의 작업 버전을 표시하기 위해 여러 편집을했다. 부모 프로세스 : 먼저'fd_toParent [PIPE_INPUT]'을 닫고 그 바로 다음부터 읽으려고합니다. 자식 프로세스 : 루프의 끝에서'fd_toChild [PIPE_INPUT]'을 닫으면 루프의 모든 추가 반복이 예상대로 작동하지 않습니다. 이러한 모든 유형의 오류는 읽기/쓰기 리턴 코드를 확인하면 쉽게 발견 할 수 있습니다. – gudok

+0

와우. 감사! –

+0

위 코드가 다른 문제도 가지고 있습니다. @gudok은'pipe'를 닫는 것에 대해서는 옳지 만'buff'을 읽지 만 다른 초기화되지 않은 변수들에서 출력하려고 시도합니다. – tijko

답변

0

여기에 프로그램에서 벗어나는 몇 가지 사항이 있습니다. 한 가지 문제는 이미에서 읽을 당신이 fd_toParent[PIPE_INPUT]을 닫고 시도 할 @gudok에 의해 지적 된 그 직후 :

close(fd_toChild[PIPE_OUTPUT]); 
close(fd_toParent[PIPE_INPUT]); 
// just closed on the preceding line 
read(fd_toParent[PIPE_INPUT], buff, sizeof(r)); 

또 다른 문제는 당신이에 read하려는 아이 과정에 값은 계산에서 작동하도록 : 여기

read(fd_toChild[PIPE_INPUT], buff, sizeof(a)); 
printf("Child reads value %d from a \n", a); 

당신이 당신의 read 버퍼로 buff을 통과 한 다음 a에서/인쇄를 운영하려고합니다. 이 경우 a이 초기화되지 않은 상태로 남겨 지므로 인쇄 할 때 왜 다시 0이 나오는지 설명 할 수 있습니다.

read(fd_toParent[PIPE_INPUT], &a, sizeof(a)); 

이 너무 b, cx 간다 대신 당신은 주소의 당신의 계수 변수의 연산자 &를 사용할 수 있습니다.

또한 부모에 결과를 출력 할 때 :

read(fd_toParent[PIPE_INPUT], buff, sizeof(r)); 

pid = wait(&status); 

fprintf(stdout, "Parent received back the result %d.\n", r); 
printf("The polynomial evaluates to %d \n", r); 

close(fd_toParent[PIPE_OUTPUT]); 

당신이 buff 전달되지만 부모 프로세스의 내부에서 초기화되지 않은됩니다 r를 인쇄 printf(The polynomial evaluates to %d \n", r) 밖으로 인쇄하고 read(fd_toParent[PIPE_INPUT], buff, sizeof(r)); 라인입니다.

로직의 대부분을 while(1) 루프 안에 넣었습니다. 부모 프로세스의 break 때문에 프로그램의 최종 결과에는 영향을주지 않지만 부모 프로세스 루프를 변경하면 close에 대한 반복 호출로 인해 파이프의 모든 끝이 종료됩니다.

while(1){ 
    .... 
    close(fd_toChild[PIPE_OUTPUT]); 
    close(fd_toParent[PIPE_INPUT]); 
} 

break 파이프를 사용하지 않아도됩니다. 당신이 많은 폐쇄로하고있는

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/wait.h> 

#define PIPE_INPUT 0 
#define PIPE_OUTPUT 1 
#define INDENT 20 


void testError(int err, const char * str) 
{ 
    if (err < 0) { 
     perror(str); 
     exit(EXIT_FAILURE); 
    } 
} 

int main(int argc, char *argv[]) 
{ 
    int fd_toChild[2], fd_toParent[2], buff; 
    pid_t pid; 

    testError(pipe(fd_toChild), "pipe"); 
    testError(pipe(fd_toParent), "pipe"); 
    testError(pid = fork(), "fork"); 

    int a, b, c, x, r; 

    if (pid > 0){  
     // this is the parent 

     int status; 

     close(fd_toChild[PIPE_INPUT]); 
     close(fd_toParent[PIPE_OUTPUT]); 

     printf("This program will evaluate a polynomial a(x^2) + bx + c. \n"); 
     printf("Please input an integer value for a: "); 
     scanf("%d", &a); 
     write(fd_toChild[PIPE_OUTPUT], &a, sizeof(a)); 

     printf("Parent writes value %d to a \n", a); 
     sleep(1); 
     printf("Please input an integer value for b: "); 
     scanf("%d", &b); 
     write(fd_toChild[PIPE_OUTPUT], &b, sizeof(b)); 
     printf("Parent writes value %d to b \n", b); 
     sleep(1); 
     printf("Please input an integer value for c: "); 
     scanf("%d", &c); 
     write(fd_toChild[PIPE_OUTPUT], &c, sizeof(c)); 
     printf("Parent writes value %d to c \n", c); 
     sleep(1); 
     printf("Please input an integer value for x: "); 
     scanf("%d", &x); 
     write(fd_toChild[PIPE_OUTPUT], &x, sizeof(x)); 
     printf("Parent writes value %d to x \n", x); 
     sleep(1); 
     // XXX you close then attempt to read from it 
     //close(fd_toParent[PIPE_INPUT]); 

     read(fd_toParent[PIPE_INPUT], &buff, sizeof(buff)); 

     pid = wait(&status); 
     // XXX Here you are showing the results as your uninitialized variable "r" 
     fprintf(stdout, "Parent received back the result %d.\n", buff); 
     printf("The polynomial evaluates to %d \n", buff); 

     close(fd_toChild[PIPE_OUTPUT]); 
     close(fd_toParent[PIPE_OUTPUT]); 
    } else { 
     // this is child 

     close(fd_toChild[PIPE_OUTPUT]); 
     close(fd_toParent[PIPE_INPUT]); 

     read(fd_toChild[PIPE_INPUT], &a, sizeof(a)); 
     printf("Child reads value %d from a \n", a); 

     read(fd_toChild[PIPE_INPUT], &b, sizeof(b)); 
     printf("Child reads value %d from b \n", b); 

     read(fd_toChild[PIPE_INPUT], &c, sizeof(c)); 
     printf("Child reads value %d from c \n", c); 

     read(fd_toChild[PIPE_INPUT], &x, sizeof(x)); 
     printf("Child reads value %d from x \n", x); 
     r = a * x * x + b * x + c; 
     printf("x is %d\n", x); 
     printf("r is %d\n", r); 

     write(fd_toParent[PIPE_OUTPUT], &r, sizeof(r)); 
     fprintf(stdout, "%*sChild is all done\n", 0, ""); 

     close(fd_toChild[PIPE_INPUT]); 
     close(fd_toParent[PIPE_OUTPUT]); 
    } 

    return EXIT_SUCCESS; 
} 
관련 문제