2016-12-08 5 views
0

私はユーザー入力を受け入れ(50の価格)、最初の子はそれを2番目に渡し、2番目のものは10(価格は今60)、もう1番目のものを渡すプログラムを作成しようとしています50(価格は現在110)、4人が最終価格を印刷/返品するだけです。私はループでフォークを持っていますが、パイプを作っていますが、価格は常に同じです。各子に10が追加されます。何が間違っているか、それを修正する方法は、私がしたいように動作するようになる。C計算のための無名パイプとフォーク

マイコード:

int main(int argc,char *argv[]) 
{ 
int anon_pipe[2]; 
int n,N=4; 
char value_price[100]; 

if(argc>1) 
{ 
    int price=atoi(argv[1]); 
    printf("%d\n",price); 
    if(pipe(anon_pipe)==-1){ 
     perror("Error opening pipe"); 
     return -1; 
    } 
    for(n = 0; n < N; n++){ 
     switch(fork()){ 
      case -1: 
       perror("Problem calling fork"); 
       return -1; 
      case 0: 
       close(anon_pipe[1]); 

       read(anon_pipe[0],value_price,100); 

       price+=10; 

       sprintf(value_price,"%d \n",price); 
       printf("Price: %d\n",atoi(value_price)); 

       write(anon_pipe[1],value_price,sizeof(value_price)); 

       _exit(0); 
     } 
    } 
    close(anon_pipe[0]); 
    sleep(1); 
    close(anon_pipe[1]); 
} 

return 0; 
} 
+0

[documentation](http:// stackoverflow。配管を介した子から子へのデータ転送を設定するための、com/documentation/posix/8082/pipes/26063/connecting-two-child-processes-via-a-pipe#t = 201612081850028838105) –

答えて

1

あなたはフォークは、プログラムの先頭から子スタートを作ることを考えているようです。これはそうではありません、フォークはfork()が例えば

呼び出されたときに子供が同じ行から開始になり、ここで、このコードを見て:

  read(anon_pipe[0],value_price,100); 

      price+=10; 

      sprintf(value_price,"%d \n",price); 
      printf("Price: %d\n",atoi(value_price)); 

あなたはpriceの値を増やしていますが読んだことがない参照してください。その値はパイプを構成します。したがって、すべての子供は常にそれぞれのパイプに+10を出力します。

0

エラーコードの関数呼び出しの戻り値を確認する必要があります。あなたが行っていた場合は、通話のこの組み合わせに起因するエラー検出されているでしょう:

  close(anon_pipe[1]); 

      // ... 

      write(anon_pipe[1],value_price,sizeof(value_price)); 

可能性が非常に高い、あなたはまた、これらの呼び出しの多くのことを検出しているだろう...

  read(anon_pipe[0],value_price,100); 

を..ファイルの終わりに何も読み込まずにシグナルを送る。最低限、read()の戻り値が必要な文字列ターミネータの配置場所を決定する必要があります(バッファを文字列として使用する前に配置できません)。原則として

、それはエラー/ EOFの可能性に加えて、これらの機能ではなく、完全なものの短いデータ転送を行うことができるため、read()write()の戻り値を処理するため必須あります。戻り値は、転送されたバイト数を示します。これは、ループしてより多くのバイトを転送しようとするかどうかを判断するために知っておく必要があります。

また、同じパイプを使用してすべてのプロセスを相互に通信する必要があります。あなたはその仕事に恵まれているかもしれませんが、少なくとも時折、あなたは通信が邪魔になることがあります。通信プロセスの各ペア(親プロセスを含む)ごとに別々のパイプを作成する必要があります。

さらに、sleep()を使用してプロセスを同期させないでください。それは確実に動作しません。代わりに、子プロセスのそれぞれについて、親プロセスはwait()またはwaitpid()である必要があります。ただし、すべてを開始して必要なパイプエンド処理をすべて実行した後でなければなりません。また、子プロセスを待っていると、終了後にかなりの時間ゾンビが残ることもありません。この場合のように、メインプロセスが他の作業に進むのではなく、それがリソースリーク(ファイル記述子)を構成するときはそれほど重要ではありません。あなたは、あなたの子プロセスを待つ良い習慣を形成する必要があります。

もちろん、書き込むことを意味するデータを実際に書き込まないと、それはすべて意味がありません。 @SanchkeDellowarはあなたの答えを説明しません。

関連する問題