11

これが私が何を意味するかを説明するための例です:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(void)
{
        int     fd[2], nbytes;
        pid_t   childpid;
        char    string[] = "Hello, world!\n";
        char    readbuffer[80];

        pipe(fd);

        if((childpid = fork()) == -1)
        {
                perror("fork");
                exit(1);
        }

        if(childpid == 0)
        {
                /* Child process closes up input side of pipe */
                close(fd[0]);

                /* Send "string" through the output side of pipe */
                write(fd[1], string, (strlen(string)+1));
            exit(0);
    }
    else
    {
            /* Parent process closes up output side of pipe */
            close(fd[1]);

            /* Read in a string from the pipe */
            nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
            printf("Received string: %s", readbuffer);
    }

   return(0);

}

ただし、一方のプロセスがパイプに継続的に書き込み、もう一方のパイプが読み取りを行う必要がある場合はどうなりますか?

上記の例は、1回の書き込みと1回の読み取りでのみ機能するようです。

4

5 に答える 5

29

パイプは単方向ストリームであり、両端にファイル記述子があります。データがパイプを通過できるようにするために、パイプのいずれかの端をclose()する必要はありません。

パイプがプロセスにまたがる場合(つまり、fork()の前に作成され、親と子がそれを使用して通信する場合)、1つの書き込みと1つの読み取りを終了できます。次に、パイプの不要な端を閉じることをお勧めします。この意志

  • 書き込み側がパイプを閉じるときに、読み取り側から見えるようにしてください。例として、子が書き込み側であり、それが死んだとしましょう。親の書き込み側が閉じられていない場合、パイプには書き込み端が開いているため、親はパイプから「eof」(長さゼロのread())を取得しません。
  • どのプロセスがパイプ上で書き込みを実行し、どのプロセスが読み取りを実行しているかを明確にします。

パイプが(同じプロセス内で)スレッドにまたがっている場合は、パイプの不要な端を閉じないでください。これは、ファイル記述子がプロセスによって保持されており、1つのスレッドで閉じると、すべてのスレッドでファイル記述子が閉じられるため、パイプが使用できなくなるためです。

一方のプロセスがパイプに継続的に書き込み、もう一方のプロセスが読み取りを行うことを妨げるものは何もありません。これが問題である場合は、詳細をお知らせください。

于 2009-06-10T14:52:23.547 に答える
12

フォークを実行した後、すべてのfdsが複製されます。各プロセスでは、パイプの両端が開いています。一方の端だけを使用する場合は、もう一方の端を閉じる必要があります(プロセスが書き込みを行う場合は、読み取りの端を閉じます)。

記述子を閉じない場合、OSは開いているファイルテーブルに余分なエントリを保持するという明らかな事実に加えて、パイプの書き込み端を閉じない場合、入力する方法がまだあるため、リーダーはEOFを受信しません。パイプへのデータ。AFAIK(およびIIRC)は、他のプロセスで読み取りfdを閉じなくても問題はありません。つまり、理由もなくファイルが開いていることを除けば問題ありません。

また、アプリケーションを終了する前にすべての記述子を閉じることをお勧めします(つまり、各プロセスで読み取り/書き込み操作が完了した後、パイプのもう一方の端を閉じます)。

于 2009-06-10T14:51:33.500 に答える
0

「上記の例は、1回の書き込みと1回の読み取りでのみ機能するようです。」

これは、1回の読み取りと書き込みの後、コードが終了するためです。連続性を実現するには、ループで書き込みを続け、ループで読み取りを続ける必要があります。FDクローズとは何の関係もないようです。以前の返信で述べたように、各プロセスの一方の端が必要なので、もう一方の端は閉じられます。

クエリを正しく理解できれば幸いです。

于 2009-06-11T10:48:16.457 に答える
0

パイプは双方向チャネルを提供せず、マルチキャストも行いません。パイプは2つの端だけであり、1つの書き込み端と複数の読み取り端はありません。

多くのリーダーが必要な場合は、リーダープロセスと同じ数のパイプが必要です。

于 2009-06-10T14:59:56.540 に答える
0

同期のみ、操作の原子性を確保するため

于 2011-07-19T08:30:57.303 に答える