0

私は、子をフォークし、2 つの別々のパイプを使用して双方向通信を行うプログラムを c で作成しようとしています。

要約;

  1. 父親はパイプ1に書き込みます
  2. 子は pipe1 から読み取り、計算を行います
  3. 子供はpipe2に答えを書きます
  4. 父親はpipe2から情報を読み取ります

ステップ 3 まではすべて順調に進んでいます。ポイント 4 のコードにコメントを付けると、すべてが機能し、pipe2 への書き込みもチェックして動作しているように見えますが、親コードで pipe2 から読み取ろうとするとハングします子の計算、ステップ 2 および 3 も実行しません。助けてください。これはこれまでの私のコードです。

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

pid_t pid;
pid_t* trabajadores;

int nHijos = 1;

trabajadores = (pid_t*)malloc(sizeof(pid_t) * nHijos);

int** aHijos;
int links = 0;

// Matriz de pipes
aHijos = (int **) malloc(sizeof(int *) * nHijos);
for (i = 0; i < nHijos; i++) {
    aHijos[i] = (int *) malloc(sizeof(int)*2);
}

int alPadre[2];
pipe(alPadre);

// Se crea el pool de procesos
for (i = 0; i < nHijos; i++) {

    pipe(aHijos[i]);
    pid = fork();

    if (pid == 0) {

        int j;
        FILE* salidaHijo;
        FILE* entradaHijo;
        char buffer2[1024];
        close(alPadre [0]);
        for (j = 0; j<i; j++) {
            close(aHijos[j][0]);
            close(aHijos[j][1]);
        }
        close(aHijos[i][1]);

        entradaHijo = fdopen(aHijos[i][0], "r");


        // STEP 2
        while ( !feof (entradaHijo) &&  fgets (buffer2, sizeof (buffer2), entradaHijo) != NULL) {
            buffer2[strcspn(buffer2, "\n")] = 0;
        }

        char* resultado;


        /* CALCULATIONS */





// STEP 3
        salidaHijo = fdopen(alPadre[1], "w");
        printf("%i\n", fprintf(salidaHijo, "%s\n", resultado));
        fflush (salidaHijo);

        exit(0);

    } else {
        trabajadores[i] = 0;
        close(alPadre[1]);
        close(aHijos[i][0]);


        // STEP 1
        FILE** salidaPadre;
        salidaPadre = (FILE**)malloc(sizeof(FILE*) * nHijos);
        for (i = 0; i < nHijos; i++) {
            salidaPadre[i] = fdopen(aHijos[i][1], "w");
        }
        fprintf(salidaPadre[j], "%s\n", DesencolarT(trabajos));
        trabajadores[j] = 1;


        sleep(5);


        // STEP 4
        char buffer[1024];
        entradaPadre = fdopen(alPadre[0], "r");
        read(alPadre[0], buffer, sizeof(buffer));
        while ( !feof (entradaPadre) &&  fgets (buffer, sizeof (buffer), entradaPadre) != NULL) {
            printf("%s\n", buffer);

        }
    }
}
return 0; 
}

それは私のコードの貼り付けられた部分にすぎません。これは、2つのプロセスの strace -ff -o test.log ./myProg からの出力です。

getdents(4, /* 0 entries */, 32768)     = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7761000
write(1, ". 160\n", 6)                  = 6
fcntl64(6, F_GETFL)                     = 0x1 (flags O_WRONLY)
fstat64(6, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7760000
_llseek(6, 0, 0xbfb8895c, SEEK_CUR)     = -1 ESPIPE (Illegal seek)
read(3, 0xbfb89738, 1024)               = ? ERESTARTSYS (To be restarted)
--- SIGINT (Interrupt) @ 0 (0) ---
+++ killed by SIGINT +++

close(3)                                = 0
close(6)                                = 0
fcntl64(5, F_GETFL)                     = 0 (flags O_RDONLY)
fstat64(5, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7761000
_llseek(5, 0, 0xbfb8895c, SEEK_CUR)     = -1 ESPIPE (Illegal seek)
read(5, 0xb7761000, 4096)               = ? ERESTARTSYS (To be restarted)
--- SIGINT (Interrupt) @ 0 (0) ---

ありがとう、スペイン語の長い投稿とひどいフォーマットでごめんなさい。


ステップ 1 と 3 の後に fflush() を使用すると、ステップ 1 の後に pipe1() を閉じるとすべてが機能するようになりました。問題は、将来その子に書き込み続ける必要があるため、閉じることができないことです。 .

4

1 に答える 1

1

親では、パイプの書き込み側を親に閉じたくありません。close(alPadre[1]);これは、後続の子がそのパイプを使用して親と通信できなくなるためです。

実際、その後のclose(alPadre[1]);ループ反復での後続の呼び出しは、親の他の「ランダムな」ファイル記述子を意図せずに閉じている可能性がありますalPadre[1]。ファイル記述子を閉じた後、おそらくその変数の値を -1 に設定して、その変数を使用した呼び出しが無効になるようにします。

別の例として、子プロセスclose(aHijos[j][0]);ですべての j < i を呼び出します。aHijos[j][0]ここでも、これらのファイル記述子のほとんどは、フォークの前に親によって以前に閉じられていたため、すべての j < i に対してたまたまファイル記述子番号が何であれ、再び「ランダムに」閉じています。

また、親は最終的に、各子との通信に使用するパイプの書き込み側を閉じる必要があります。そうしないと、子は入力ループで次の入力を永遠に待機します。これが、ステップ #4 で親がハングする理由である可能性があります。これは、親からのパイプで EOF を待っているステップ #2 で子供がハングするためです。

于 2015-03-05T06:29:05.150 に答える