0

我在 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;

}                                           

如果我执行此操作,则父母似乎会永远等待孩子。我的流的配置方式有什么明显的问题吗?如果我有它,所以孩子只读而父母只写(或相反),它工作正常,但我无法管理让两个进程都读写。顺序似乎很好,孩子先期待标准输入,父母先写。

谢谢。

4

2 回答 2

2

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

试试看man 3 setvbuf

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

         _IONBF unbuffered
         _IOLBF line buffered
         _IOFBF fully buffered

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

于 2013-09-27T14:05:34.327 回答
0

dup2手册页:

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

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

于 2013-09-27T13:39:42.190 回答