使用管道,重定向和文件流与子进程通信

时间:2013-09-27 13:06:13

标签: c unix pipe

我在使用C语言实现进程间通信时遇到了一些困难。我已将问题简化为以下代码块,其中我创建管道,分叉进程,并为子进程重定向IO:

int main(void) {
    int parentToChild[2];
    int childToParent[2];
    pid_t pid = 1;
    char buffer[80];
    FILE *writeStream;
    FILE *readStream;

    pipe(parentToChild);
    pipe(childToParent);

    pid = fork();

    if(pid == 0) { // I'm the child. I read from stdin, and write to stdout.
        close(parentToChild[1]);
        close(childToParent[0]);
        dup2(parentToChild[0], 0);
        dup2(childToParent[1], 1);
        close(parentToChild[0]);
        close(childToParent[1]);
        fgets(buffer, 80, stdin); // wait for the parent to send something
        fprintf(stderr, "I got %s\n", buffer); // tell the world I got it
        fprintf(stdout, "Child message\n"); // send message back to the parent
    }

    if(pid != 0) { // I'm a parent
            close(parentToChild[0]);
            close(childToParent[1]);
            /* writeStream connected to stdin of child */
            writeStream = fdopen(parentToChild[1], "w");
            /* readStream connected to stdout of child. */
            readStream = fdopen(childToParent[0], "r");
            fprintf(writeStream, "Hello, World!\n");
            fgets(buffer, 80, readStream); // comment this out and the child will be able to read the "Hello World". Why is this?
            fprintf(stderr, "Parent just got %s", buffer);
    }



    return 0;

}                                           

如果我执行此操作,父母似乎永远等待孩子。我的流如何配置有什么明显的错误吗?如果我拥有它所以孩子只是阅读而父母只是写作(或反过来),它工作正常,但我无法管理两个进程读写。这个顺序看起来很好,孩子先期待stdin,父亲先写一个。

感谢。

2 个答案:

答案 0 :(得分:2)

当我fflush (writeStream)在父母fprintf(writeStream, "Hello, World!\n")之后,一切正常。 我相信管道的缓冲存在问题。

尝试查看man 3 setvbuf

  

setvbuf()函数可用于任何打开的流来更改其缓冲区。 mode参数必须是以下三个宏之一:

         _IONBF unbuffered
         _IOLBF line buffered
         _IOFBF fully buffered

所以我想将你的writeStream设置为_IONBF(无缓冲)可以解决问题。

答案 1 :(得分:0)

来自dup2手册页:

  

在从这些系统调用之一成功返回之后,旧文件描述符和新文件描述符可以互换使用。 他们引用相同的打开文件说明

因此,关闭其中一个管道将关闭其中一个标准文件描述符。不要那样做。