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

第一个可以使用一些同步技术来完成。意味着孩子应该等到父母读取数据或在您的代码中父母终止。我在用于此同步的代码中添加了第二个管道。

写入后的孩子只是等待从该管道读取并在读取中被阻塞。

只有当父级终止时,函数 read 才会返回(此处为 0),因为现在读取子级将获得文件结束通知,这是由于父级退出后管道在父级中的写入端关闭。(写端会在父级终止后自动关闭,我没有明确添加)

你的第二个要求

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 回答
0

以下代码演示,在孩子写入管道后,父母可以读取管道。不需要子进程关闭管道或终止。

#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);
        sleep(10);
        close(fd[WRITE]); /* Close used end */
        sleep(20);
    } 
    else { /* Parent, reader */
        printf( "child ipd = %d\n\r", pid);
        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 */
        sleep(10);
    }
}
于 2019-08-22T14:54:00.823 回答