2017-11-27 9 views
0

子プロセスのリダイレクトのトピックを理解しようとします。親プロセスがそれを読み取って非常に奇妙な動作に直面する可能性のある標準出力パイプです。この例の親プロセスでは、単純なファイル検索を行い、出力を取得する3つの子プロセスをforkします。 最初の結果のみが届きます。この例で何が間違っているのでしょうか?子プロセスのリダイレクションCのパイプへの標準出力

コードは次のようになります。ここでは

char * searches[] = { 
      ".bashrc", 
      "NM34_x64.exe", 
      "blacklist.sh" 
    }; 
    int fd[2]; 
    if (pipe(fd) == -1) { 
     error("Can't create the pipe"); 
    } 
    __pid_t pids[sizeof(searches)/sizeof(char*)]; 

    for(int i = 0; i < sizeof(searches)/sizeof(char*); i++){ 
     __pid_t pid = fork(); 

     switch (pid) { 
      case -1 : 
       // ERROR CASE 
       error("Failed to make a child process"); 
       break; 
      case 0 : 
       // CHILD CASE 
       // 1. Redirect Standard Output to pipe 
       dup2(fd[1], 1); 
       close(fd[0]); 
       // 2. Execute command 
       if (execl("/usr/bin/find", "/usr/bin/find", "/home", "-name", searches[i], NULL) == -1) 
        error("Failed to execute the command in the child process"); 
       break; 
      default: 
       // PARENT CASE 
       printf("Created child process with pid %d\n", pid); 
       pids[i] = pid; 
       // 1. Wait for PID to finish 
       int status; 
       waitpid(pids[0], &status, 0); 
       if (status == -1) 
        error("Failed to wait the child PID"); 
       printf("Process %d finish his work\n", pids[i]); 
       // 2. Redirect pipe to Standard Input 
       dup2(fd[0],0); 
       close(fd[1]); 
       // 3. Read Standard Input 
       char line[255]; 
       while (fgets(line,255,stdin)) { 
        printf("%s", line); 
       } 
       break; 
     } 
    } 
    return 0; 

が出力されます:

Created child process with pid 5063 
Process 5063 finish his work 
/home/user/.bashrc 
Created child process with pid 5064 
Process 5064 finish his work 
Created child process with pid 5065 
Process 5065 finish his work 
+0

一般的なパターンは 'close(fd [0])です。 dup2(fd [1]、1); close(fd [1]) 'を実行します。ファイル記述子を開いたままにしておきます。 –

+0

親は最初の子を待ってから 'fd [1]'を閉じます。 2番目の子がforkされると、 'fd [1]'はすでに閉じられていて、書き込めません。これを 'strace -f'の下で実行して、2番目と3番目の子プロセスが書き込みに失敗するのを見ることができます。 – Useless

+0

これをより良く解決する方法は? – javadev

答えて

0

あなたはプロセス間通信用のパイプを使用している場合は、直接の代わりにパイプからメインプロセスへの入力を読みますそれを再び標準入力にリダイレクトし、メインプロセスでそれを読み取ることです。

関連する問題