2016-01-20 105 views
1

溝通我想寫這個小程序,父母和孩子通過管道相互溝通,這裏的代碼工作,除非你'取消註釋'註釋行,比它涉及到某種的僵局,我無法弄清楚爲什麼?有任何想法嗎?通過管道在C

int main(int argc, char **argv){ 

    int fd[2]; 
    int fd2[2]; 
    pid_t pid; 
    pipe(fd); 
    pipe(fd2); 
    pid = fork(); 

    if(pid==0){ 
     close(fd[1]); 
     dup2(fd[0],fileno(stdin)); 
     close(fd2[0]); 
     FILE *output = fdopen(fd2[1],"w"); 
     char buffer[255]; 
     while(fgets(buffer,255,stdin)!=NULL) 
      printf("child: %s",buffer); 
    // fprintf(output,"%s",buffer); 
    } else { 
     close(fd[0]); 
     close(fd2[1]); 
     FILE *output = fdopen(fd[1],"w"); 
     char buffer[255]; 
     while(fgets(buffer,255,stdin)!=NULL) 
      fprintf(output,"%s",buffer); 
     //FILE *input = fdopen(fd2[0],"r"); 
     //while(fgets(buffer,255,input)!=NULL) 
     // printf("Parent: %s",buffer); 
    } 

    return 0; 
} 
+0

你覺得哪個進程應該首先終止,父母或孩子? –

+0

@DavidSchwartz的孩子。但是,如果我等待子進程,那麼它又是一個僵局。 – TimNeutron

+0

孩子如何終止?它的'while'循環等待它的'stdin'關閉。父母關閉它在哪裏?父母中的「close(fd [1])」在哪裏? –

回答

1

父級需要關閉管道的一側給孩子,以便孩子能檢測到文件結束並終止。

while(fgets(buffer,255,stdin)!=NULL) 
     fprintf(output,"%s",buffer); 
    fclose(output); // does close(fd[1]); 
    FILE *input = fdopen(fd2[0],"r"); 
    while(fgets(buffer,255,input)!=NULL) 
    printf("Parent: %s",buffer); 
+0

謝謝你現在沒有更多的僵局!但是,輸出是亂碼......任何想法爲什麼? – TimNeutron

+0

噢好吧......我超累了,我沒有關閉(fd [0])而不是fclose(輸出)。謝謝先生,你就像一個調試忍者 – TimNeutron

1

確保一切都關閉。

dup2(fd[0],fileno(stdin)); 

後,你應該做的:

close(fd[0]); 
1

當你有兩個(單線程)進程之間的輸入和輸出管道,你可以有一些deadlock,所以你需要使用有一個event loop一個多路複用系統調用(通常爲poll(2) ...),您可以讀取或寫入,具體取決於可能的情況。當然你需要緩衝!順便說一句,在這種情況下,你最好使用低水平syscalls(2)而不使用<stdio.h>(如果你仍然使用stdio,不要忘記fflush(3) ....)。另見this answer

(當然我假設一個POSIX或Linux系統)