2

コマンド pipe() が C でどのように機能するかを理解するのに苦労しています。私の知る限り、匿名パイプは 2 つの「関連する」プロセス間で情報を送受信するために使用されます。
対応するファイル記述子への/からの読み取りおよび書き込みの条件が非常にわかりにくく、書き込みおよびその逆のために読み取り fd を閉じる必要がある理由と、これを使用してプロセスをブロックする方法がわかりません。別の人が読み書きしました。

パイプを使用してプロセスを同期するにはどうすればよいですか? たとえば、pipe() を使用して次のプロセス階層をどのように実装しますか?

A / B ----D\
  \ C ------\
             E


-A は、B と C が作成される前に終了する必要があります。
-B は、D が作成される前に終了する必要があります。
-C と C は、E が作成される前に終了する必要があります。
-B と C は任意の順序で終了する可能性があり

ます。

4

2 に答える 2

2

あなたが言及したプロセス同期をシミュレートし、コメントも提供しました。コンセプトが明確になることを願っています。

ここでは、パイプを介してデータが読み取られることはありません。パイプの書き込み側がまだ開いているときに、読み取り関数のブロッキング特性を使用して同期を達成するためにのみ使用されます。

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
#define MAXBUF 1

int main(){

    int ret, i, fd[2];
    char buf[MAXBUF];

    //Create a Pipe
    pipe(fd);

    ret = fork();//Creating process A
    if (0 == ret)
    {
            printf("Process - A created\n");
            exit(0);
    }
    //I need to wait till Process - A completes
    //Let me close my write end else I will be blocked for ever in the loop below
    close(fd[1]);

    //Waiting over reading the pipe -> The loop will come out when Process A exits
    //Why ->since all the write ends of the pipe are closed, so read returns 0
    while ((ret = read(fd[0], buf, MAXBUF)) > 0)
    {
            //Just Wait, the read blocks till A exits and then read returns 0
    }
    //Again a pipe to synchronise B and C
    pipe(fd);

    //Lets Create Now  B and C

    ret = fork();
    if (0 == ret)
    {
            printf("Process - B created\n");
            exit(0);
    }
    ret = fork();
    if (0 == ret)
    {
            printf("Process - C created\n");
            exit(0);

    }
    //Let me close my Write End of pipe
    close(fd[1]);

    //Here Waiting for Termination of both B and C who can terminate in any order.
    while ((ret = read(fd[0], buf, MAXBUF)) > 0)
    {
            //This loop will turn false only if both B & C have exited.
            //Since both the write ends of the pipe that
            //were there in B and C will no longer be available
            //after they exit and thus the read will return 0
            //Just Wait ..Do nothing
    }
    //Now all A, B, C are finished.
    //Create D and E
    ret = fork();
    if (0 == ret)
    {
            printf("Process - D created\n");
            exit(0);
    }
    ret = fork();
    if (0 == ret)
    {
            printf("Process - E created\n");
            exit(0);

    }
//Here let the main process wait for all the 5 Child to complete
    //This is not needed, but I gave given so that the Shell
    //Prompt is shown after the code exits..
    //If this is deleted then you need to press return
    //to get back the shell prompt after the code completes execution.
    for (i = 0; i < 5; i++)
    {
            wait(NULL);
    }

}
于 2012-08-19T19:30:45.030 に答える
1

いずれにせよ、パイプはプロセスの同期には使用されません。代わりに、それはコミュニケーションの方法です。

たとえば、プロセスはパイプのペア (1 つの書き込み側と 1 つの読み取り側) を作成し、次に fork して新しい子プロセスを作成します。その後、親はパイプを介して子プロセスにデータを送信できます。

于 2012-08-19T17:43:01.927 に答える