2017-11-18 32 views
0

私はパイプを使って簡単なプログラムを作ろうとしています。プログラムは、親の整数配列を要求し、それを子に送信しなければなりません。子は、配列をソートしてそれを親に返さなければなりません。 問題は、パイプを介して送信した後、どのように子の配列値を読み取るのか分かりません。パイプを使ってIntの配列を書き込んで読み込み

私のコードは、次のとおりです。

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

int main() { 

int fd[2]; 
pid_t pid; 

/* Verifica se ocorreu erro (-1) ao criar o PIPE */ 
if(pipe(fd) == -1){ 
    perror("pipe"); 
    exit(1); 
} 

/* Verifica se o fork foi realizado com sucesso > 0 */ 
if((pid = fork()) < 0){ 
    perror("fork"); 
    exit(1); 
} 

if(pid > 0){ 

    printf("-----------------------------------------------\n"); 
    printf("    PROCESSO PAI     \n"); 
    printf("-----------------------------------------------\n"); 

    /* Como vamos ESCREVER do lado do PAI, fechamos a LEITURA */ 
    close(fd[0]); 

    int numeros[5]; 

    for (int i = 0; i < 5; i++){ 
     printf("\nDigite o numero [%d]: ", i); 
     scanf("%d", &numeros[i]); 
    } 

    /* Escrevendo o array no PIPE */ 
    write(fd[1], numeros, sizeof(numeros) + 1); 
    printf("\nEnviando numeros para meu Filho...\n"); 
    exit(0); 

}else{ 

    int numeros_recebidos[5]; 

    /* Como vamos LER do lado do FILHO, fechamos a ESCRITA*/ 
    close(fd[1]); 

    /* Lendo a mensagem que foi enviada pelo FILHO */ 
    read(fd[0], numeros_recebidos, sizeof(numeros_recebidos)); 
    printf("\n-----------------------------------------------\n"); 
    printf("    PROCESSO FILHO     \n"); 
    printf("-----------------------------------------------\n"); 

    printf("\nNumeros Recebidos, Ordenando...\n"); 


    for(int i = 0; i<5; i++){ 
     printf("%d \n", &numeros_recebidos[i]); 
    } 
} 

return 0; 
} 
+0

2つのパイプが必要です.1つは、親にデータを子に送信するパイプと、子が親にデータを送信するパイプです。それ以外のものは信頼できません。親はそれが書いたデータを読み終えるかもしれない。せいぜい、「読み取る整数の数とそのデータを子に送信する」などのプロトコルを持つ必要があります。もう一度寝る。子どもからの応答を読んでください。それは形式的に保証されていません。プロセスのスケジューリングは予測不可能であり、システムが耐え難いほどビジー状態であれば、子どもは1秒間スケジュールされないかもしれません(ただし、問題はほとんどありません)。 –

答えて

2

プログラムがどのように子供と親がパイプを介して通信している

for(int i = 0; i<5; i++){ 
     printf("%d \n", &numeros_recebidos[i]); // why &, remove it bcz you are printing data not scanning. 

のようないくつかのバグを除いて正常に動作している:いくつかの重要ながあります

をパイプに関するもの():

1)pipe()システムコールでは、fd[0]fd1[1という2つのエンドが作成されます。 1つはreading用に予約されており、別の1つはwriting用に予約されています。

2)pipeは、パイプの一端からの読み取りまたは書き込みのみが可能な時点で、同時に実行することはできません。uni-directional IPCです。

3)唯一関連処理(子供のように&親)はpipe()で通信できます。

親プロセス:親プロセスは、fd[1]に整数の配列を書き込みます。一度それが完了したら、データは書面エンドでpipe()にあります。次は、ここからデータを読み込む子ジョブです。子プロセスにジャンプしましょう。

      pipe(uni-directional) 
         |---------------------------| 
parent is writing----->|       |<--------- 
         |---------------------------| 
        fd[1]      fd[0] 

     write(fd[1], numeros, sizeof(numeros) + 1); 

child process:親がFDにint配列をパットしている[1]今の子供は、FDからの読み込みにあり[0]と、それを印刷します。

  pipe(uni-directional) 
     |---------------------------| 
----->|       |<-----child process is reading data & storing in numeros_recebidos 
     |---------------------------| 
    fd[1]      fd[0] 

    read(fd[0], numeros_recebidos, sizeof(numeros_recebidos)); 

私はそれがpipe()の働きを理解するのに役立つことを望みます。

+1

パイプを使用する場合、パイプの未使用の端を閉じて、EOF条件が期待通りに検出されるようにすることが非常に重要です。いずれかのプロセスがパイプの書き込み終了を持っている場合、そのプロセスだけが読み取りプロセスであっても、読み取りプロセスはパイプの読み取り側でEOFを検出せず、書き込みを待つ読み取りで無期限にハングします決して起こることはありません。また、ファイル記述子のペアの0要素は読み込み終了(0 =標準入力)なので、書き込むべきではありません。 1要素は書き込み終了(1 =標準出力)であり、決して読み取られるべきではありません。 –

関連する問題