2014-03-04 7 views
1

나는 child1에서 실행중인 C.the prog1에서 2 개의 파이프를 사용하여 부모 프로세스와 자식 프로세스 간의 양방향 통신을 만들려고합니다. prog1에서 3 + 4 + 5를 읽고 싶습니다. 쓰기로 prog1에 뭔가를 보내지 만 할 수 없었습니다. 어디가 잘못 되었나요?부모와 자식 간의 양방향 파이프 통신

/* prog1.c */ 

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
void 
main(void){ 
    int FD; 
unsigned int buf; 
char buf[15]; 

printf("7+5+11=?\n"); 
FD=read(0,buf,10); 
if(FD<0){ 
    perror("FAIL\n"); 
exit(EXIT_FAILURE); 
} 
    printf("TAKED:%s\n",buf); 
} 

prog2.c

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/wait.h> 
void ERR_SYS(const char *msg); 
int 
main(void){ 
    char buf[15]; 
    int pipe1[2]; 
    int pipe2[2]; 
    pid_t childpid; 

    memset(buf,'\0',14); 

    if(pipe(pipe1) < 0 || pipe(pipe2) < 0) 
    ERR_SYS("fail_pipe"); 

    if((childpid = fork()) < 0) 
    ERR_SYS("fail_fork"); 

    if(childpid==0) 
    { 
     dup2(pipe2[1],1); 
      dup2(pipe1[0],0); 
     close(pipe1[1]); 
      close(pipe2[0]); 
     close(pipe2[1]); 
     close(pipe1[0]); 
      //close(1); 
      //close(0); 
     execle("./prog1",NULL,NULL,NULL); 
    }else{ 

    close(pipe1[0]); 
    close(pipe2[1]); 
    read(pipe2[0],buf,4); /*I hope to read 3+4+5*/ 
    printf("BuF::%s\n",buf); 
    write(pipe1[1],"off",3);/*send {off}*/ 
    wait(NULL); 
    } 
return 0; 
} 

void 
ERR_SYS(const char *msg) 
{ 
    perror(msg); 
    exit(EXIT_FAILURE); 
} 
+1

체크 반환 값 및 쓰기의 내용이다 :

여기 내 prog3.c의 내용입니다! "나는 할 수 없다"는 것은 무엇을 의미합니까? 프로그램은 어떻게 작동합니까? – zoska

답변

1

프로그램에 몇 가지 문제가 있습니다 prog2.c에

  1. 당신은 읽기의 반환 값을 확인하지 않는, 쓰기 및 execle는
  2. 너는 길고 10 자이지만 4자를 기대하는 "7 + 5 + 11 =? \ n"문자열을 보냈습니다 (3 + 4 + 5는 4 자조차도 아닙니다).
  3. 보내시는 "꺼짐"문자는 3 자이지만 Null 종료를 포함하지 않습니다.
  4. fd에서 읽을 때 두 경우 모두 null로 끝나는 문자열을 얻지 못하면 printf을 시도합니다. 정의되지 않은 동작을 빠르게 수행 할 수 있습니다. 어떤 파일 기술자로부터 읽은 버퍼의 끝 뒤에 '\ 0'을 넣으십시오!
  5. 특히 read이 반환하는 문자는 몇 개의 문자를 읽었는지 알려주기 때문에 매우 중요합니다. 반환 된 값인 read을 무시해서는 안됩니다 (어떤 경우에는 write 함수와 동일합니다).

다음 번에는 프로그램 출력을 제공하기 때문에 도움이 될 것입니다.

+0

Additionl 문제 - 기본적으로'printf'는 나중에 쓰여질 데이터를 버퍼링합니다. 실제로 쓰여지는 확실한'fflush' 호출이 필요합니다. 이것은 프로그램을 멈추게하는 원인입니다. 자식과 부모 모두는 실제로 읽혀진 데이터없이'read'에서 기다리는 것을 막습니다. 그러나'fflush'를 추가하면 여기에서 확인 된 다른 모든 문제들에 빠지게 될 것입니다 ... –

0

필자는 파이프 설정에 대한 모든 논리를 따르지 않았으므로 원본을 수정하고 잘게 명료화했습니다. 어떤 이유로 든 외부 프로그램의 (prog1) 관점에서 fd_in 및 fd_out을 지정했습니다 (예 : fd_out은 prog1이 쓰는 위치이고 fd_in은 prog1이 읽는 곳입니다).

... 
#define READ_END 0 
#define WRITE_END 1 
void ERR_SYS(const char *msg); 
int main(void) { 

    char buff[15]; 
    char *msg = "hello"; 
    int fd_out[2]; 
    int fd_in[2]; 
    int nbytes; 
    pid_t childpid; 

    if(pipe(fd_out) < 0 || pipe(fd_in) < 0) { 
      ERR_SYS("fail_pipe"); 
    } 

    if((childpid = fork()) < 0) { 
      ERR_SYS("fail_fork"); 
    } 

    if(childpid==0) { //child 
      //connect the write end of fd_out to stdout 
      dup2(fd_out[WRITE_END], STDOUT_FILENO); 
      close(fd_out[WRITE_END]); 
      //connect the read end of fd_in to stdin 
      dup2(fd_in[READ_END], STDIN_FILENO); 
      close(fd_in[READ_END]); 
      //the exec'd prog1 will inherit the streams 
      execlp("./prog1", "prog1", NULL); //TODO: check return 
    } else { //parent 
      nbytes = write(fd_in[WRITE_END], msg, strlen(msg)); 
      //TODO: handle any errors from write 
      nbytes = read(fd_out[READ_END],buff,sizeof(buff)-1); 
      //TODO: handle any errors from read 
      buff[nbytes] = '\0'; 
      printf("contents of buff::%s",buff); 
    } 
    return 0; 
} 
void ERR_SYS(const char *msg) { 
    perror(msg); 
    exit(EXIT_FAILURE); 
} 

을 그리고 여기 내 prog1.c

int main(void){ 
    char buff[15]; 
    int nbytes; 
    nbytes = read(STDIN_FILENO, buff, sizeof(buff)-1); 
    buff[nbytes] = '\0'; 
    printf("%s world\n", buff); 
    return 0; 

} 읽기

관련 문제