2016-03-25 4 views
2

すべてのパイプが閉じている場合でも、入力を取りたい:プログラムは、まだ私はこのシナリオを実現しようとしています

2の並列処理が tr /a-z/ /A-Z/にパイプされ、最終的に tr /a-z/ /A-Z/プロセスが標準出力に接続されている

fork and pipe scenario

私は自分の目標を達成しようとするこのプログラムを書いている:

#include<stdio.h> 
#include<unistd.h> 
#include<wait.h> 

int main() 
{ 
    int dummy; 
    int fd[2]; 
    int i; 
    char* lsargs[] = {"/bin/ls", "-l", NULL}; 
    char* lsargs2[] = {"cat", "/etc/group", NULL}; 
    char* lsargs3[] = {"tr", "/a-z/", "/A-Z/", NULL}; 
    char** am[] = {lsargs, lsargs2, lsargs3}; 

    pipe(fd); 

    for (i = 0 ; i < 3 ; i++) 
    { 
     pid_t pid = fork(); 

     if (pid == 0) 
     { 
      if (i != 2) // ls -l & cat 
      { 
       // 0 -> stdin, 1 -> pipe write end 
       close(fd[0]); 
       dup2(fd[1], 1); 
       close(fd[1]); 
       execvp(am[i][0], am[i]); 
      } 
      else //TR AZ AZ 
      { 
       // 0 -> pipe read end 1 -> stdout 
       close(fd[1]); 
       dup2(fd[0],0); 
       close(fd[0]); 
       execvp(am[i][0], am[i]); 
      } 
      break; 
     } 
     else{ 
      wait(&dummy); 
     } 
    } 

    return 0; 
} 

私は正しい出力を得ることが、私のプログラムが終了していない、それはまだ入力を取りたいです。理由を理解するのを助けてくれますか?

+1

最初のプロセスをフォークした後で待機しています。あなたのループはあまりにも賢いです、私はあなたがループを展開することをお勧めします –

+0

@AnttiHaapala何をお勧めしますか?私はループを使用することは意味がないことを知っている、私はそれを特別な目的のために使用した。 –

+1

'for'を使用する代わりに、コードを繰り返して繰り返します。どの部分を繰り返すことができるのか、その理由を認識することができます。今度は、あなたの親は、最初の子が終了する前に待つ* *次の子もforkされ、実行されず、パイプが走っていません。 –

答えて

1

トップレベルプロセスがパイプを閉じていません。親プロセスは実際にコーディネータであり、実際にパイプを使用しないので、最後のすべてのforkコールが行われたら両端を閉じる必要があります。これを行う1つの方法は、elseケースにクローズコードを追加することです。例:

else { 

    /* ADDED CODE - close the pipes after last fork */ 
    if (i == 2) { 
     close(fd[0]); 
     close(fd[1]); 
    } 

    wait(&dummy); 
} 
+0

コードは私が望むように動作しますが、Antti Haapalaのメインポストでのコメントは私には不思議に思っています。私はwait(&dummy)を使いますか?そうでない場合は、どうすれば適切に使用できますか? –

+1

@ArdaGüneyそれはあなたの望む行動が何であるかによって異なります。 'ls'と' cat'の出力を順番に並べ替えるためには、あなたの現在の待機動作は正しいです。少なくとも最初の 'fork 'の後で待たなければ' ls'と 'cat'出力は' pipe'に同時に書き込もうとするのでインターリーブされる可能性があります。出力順序は次のようになります。 – kaylum

+0

私はゾンビを残しておらず、またlsとcatを同時に実行させる方法を理解できません。 wait(&dummy)のための 'if(i!= 0)'文を追加することはできません。 –

関連する問題