2014-03-04 155 views
1

我試圖在C中使用2個管道在父子進程之間創建雙向通信。prog1在child1中運行 我想從prog1讀取3 + 4 + 5發送一些東西與編寫,但我不能。 錯在哪裏?父母和孩子之間的雙向管道通信

/* 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

檢查返回值,寫的內容!這是什麼意思「我不能」?程序如何運作? – zoska

回答

1

有與程序幾個問題:在prog2.c

  1. 你是不是檢查讀取的返回值,寫和execle
  2. 您正在發送10個字符長的「7 + 5 + 11 =?\ n」字符串,但只需要4個字符(3 + 4 + 5甚至不是4個字符)。
  3. 您發送的「關閉」長度爲3個字符,但不包括空終止。
  4. 當您從fd讀取時,您將在兩種情況下都不會得到以空字符結尾的字符串,然後您正在嘗試printf它。這是未定義行爲的快速方法。在從任何文件描述符讀取的緩衝區結束後放置一個'\ 0'!
  5. 特別是什麼read返回是非常重要的,因爲它告訴你讀了多少個字符。你永遠不應該忽略返回的值read(在某些情況下,它與write函數相同)。

下次還提供一些程序輸出,因爲它會更容易給一些幫助。

+0

附加問題 - 默認情況下''printf'只是緩衝稍後要寫入的數據 - 您需要明確的'fflush'調用來確保其實際寫入。這是導致程序掛起的原因 - 孩子和父母都被阻止在'read'中等待,而沒有實際寫入任何數據。但是在添加'fflush'之後,你會遇到所有其他問題...... –

0

我沒有按照你的設置管道的所有邏輯,所以我修改並希望澄清你的原始。我應該注意,無論出於何種原因,我從外部程序的(prog1)的角度來命名fd_in和fd_out(例如,fd_out是prog1正在寫入的地方,fd_in是prog1正在讀取的地方)。

這裏是我的prog3.c的內容:

... 
#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; 

}讀

相關問題