5

以下のコードは、子プロセスがパイプの端に書き込む方法と、親プロセスがもう一方の端から読み取る方法を示しています。コードを試した後で気付いたのは、子プロセスが終了した後でのみ、親がデータを読み取ることができるということです。

親プロセスを強制的にフォアグラウンドにして、子がwrite()を呼び出した直後にデータを読み取る方法はありますか?そして、子供を終了せずにデータを読み取る方法はありますか?

#include <stdio.h> /* For printf */
#include <string.h> /* For strlen */
#include <stdlib.h> /* For exit */

#define READ 0 /* Read end of pipe */
#define WRITE 1 /* Write end of pipe */
char *phrase = "This is a test phrase.";
main(){
    int pid, fd[2], bytes;
    char message[100];

    if (pipe(fd) == -1) { /* Create a pipe */
        perror("pipe"); 
        exit(1); 
    }
    if ((pid = fork()) == -1) { /* Fork a child */
        perror("fork"); 
        exit(1); 
    }
    if (pid == 0) { /* Child, writer */
        close(fd[READ]); /* Close unused end */
        write(fd[WRITE], phrase, strlen(phrase)+1);
        close(fd[WRITE]); /* Close used end */
    } 
    else { /* Parent, reader */
        close(fd[WRITE]); /* Close unused end */
        bytes = read(fd[READ], message, sizeof(message));
        printf("Read %d bytes: %s\n", bytes, message);
        close(fd[READ]);  /* Close used end */
    }
}
4

4 に答える 4

2

あなたは正しくありません。sleep(120)「子」部分のパイプの書き込み終了を閉じる直前に呼び出しを追加して、アプリケーションを実行してみてください。

于 2012-09-29T01:39:05.453 に答える
1

1つ目は、いくつかの同期手法を使用して実行できます。親がデータを読み取るまで、またはここで親が終了するまで、子が待機する必要があることを意味します。この同期に使用されるコードに2番目のパイプを追加しました。

書き込み後の子は、単にそのパイプからの読み取りを待機し、読み取りでブロックされます。

親が終了した後、親のパイプの書き込み終了が閉じられるため、親が終了したときにのみ、関数readは(ここでは0)を返します。これは、親で読み込まれた子がファイルの終了通知を受け取るためです。(親が終了すると、書き込み終了は自動的に閉じられます。明示的に追加していません)

2番目の要件

I also want the parent to read the data immediately after the child whites to
the pipe. 

なぜこれが起こっていないと思いますか?常にわずかなタイムラグがあるはずです。

#include <stdio.h> /* For printf */
#include <string.h> /* For strlen */
#include <stdlib.h> /* For exit */

#define READ 0 /* Read end of pipe */
#define WRITE 1 /* Write end of pipe */
char *phrase = "This is a test phrase.";
main(){
  int pid, fd[2], bytes;
  char message[100];
  int fd1[2];
  char buffer[1];
  int ret;

  if (pipe(fd) == -1) { /* Create a pipe */
    perror("pipe");
    exit(1);
  }
  if (pipe(fd1) == -1) { /* Create a pipe */
    perror("pipe");
    exit(1);
  }
  if ((pid = fork()) == -1) { /* Fork a child */
    perror("fork");
    exit(1);
  }
  if (pid == 0) { /* Child, writer */
    close(fd[READ]); /* Close unused end */
    close(fd1[WRITE]);/*Close write  end of the 2nd pipe*/
    write(fd[WRITE], phrase, strlen(phrase)+1);
    close(fd[WRITE]); /* Close used end */
    /*For synchronisation let the child try to
    read from the 2nd pipe. 
    The function read, will return 0 only when the
    parent terminates and in this we are
    not interested if at all anything read or not.
    The read statement below, will return only if the
    parent has terminated, thus ensures that the
    child terminates only after the parent*/
    ret = read(fd1[READ],buffer, 1);
  }

else { /* Parent, reader */
    close(fd[WRITE]); /* Close unused end */
    close(fd1[READ]); /*Close read end of the 2nd pipe*/
    bytes = read(fd[READ], message, sizeof(message));
    printf("Read %d bytes: %s\n", bytes, message);
    close(fd[READ]);  /* Close used end */

   }
}
于 2012-09-29T12:20:22.100 に答える
0

fd[0]=0 と fd[1]=0 を初期化する必要があります

于 2016-04-11T06:36:10.933 に答える