【问题标题】:Two-Way Parent Child Communication Using 2 Pipes in C on Linux在 Linux 上使用 C 中的 2 个管道进行双向父子通信
【发布时间】:2012-02-16 19:54:04
【问题描述】:

我正在尝试在 Linux 上使用 2 个管道在父进程和子进程之间创建双向通信。父程序是我的程序,子程序只是一个随机程序(比如“猫”)。

我尝试在父级中使用 read() 来读取子级输出,但它给了我 errno 9,这是错误的文件描述符。

以下是我的代码

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define Read            0
#define Write           1
#define ParentRead      read_pipe[1]
#define ParentWrite     write_pipe[0]
#define ChildRead       write_pipe[1]
#define ChildWrite      read_pipe[0]

int main()
{
    int data_processed;

    /** Pipe for reading for subprocess */
    int read_pipe[2];
    /** Pipe for writing to subprocess */
    int write_pipe[2];

    char buffer[100];
    memset(buffer, '\0', 100);

    if (pipe(read_pipe) == 0 && pipe(write_pipe) == 0)
    {
        pid_t pid = fork();
        if (pid == (pid_t)-1)
        {
            fprintf(stderr, "Fork failure");
            exit(EXIT_FAILURE);
        }
        else if (pid == (pid_t)0) //Child process
        {
            close(Read);
            close(Write);
            close(ParentRead);
            close(ParentWrite);
            dup(ChildRead);
            dup(ChildWrite);
            execlp("cat", (char*)NULL);
            exit(EXIT_FAILURE);
        }
        else { //Parent process
            close(ChildRead);
            close(ChildWrite);

            write(ParentWrite, "abc", 3);
            int r = read(ParentRead, buffer, 99);
            printf("%d %d", r, errno);
            puts(buffer);
        }
    }

    exit(EXIT_SUCCESS);
}

【问题讨论】:

  • 在执行 I/O 之前打开()管道。
  • (pipe(read_pipe) == 0 && pipe(write_pipe) == 0) 和打开管道不一样吗?

标签: c linux process communication pipe


【解决方案1】:

如果要将标准输入和标准输出重定向到管道,则需要使用 dup2(2) 系统调用。

dup2 (ChildRead, 0);
dup2 (ChildWrite, 1);

附: 我还发现管道中读/写的错误方向。这是正确的方法

#define ParentRead      read_pipe[0]
#define ParentWrite     write_pipe[1]
#define ChildRead       write_pipe[0]
#define ChildWrite      read_pipe[1]

记住:pipe[0] 是读取的 fd,pipe[1] 是写入的 fd。

还有一个错误,在 execlp 中。不要忘记将发送给执行程序的第一个参数设置为程序的名称

execlp("cat", "cat", (char*)NULL);

【讨论】:

  • 我将所有 dup() 更改为 dup2(),但仍然得到相同的结果。 read() 返回 -1,错误码为 9。
  • 我怎么这么粗心。我什至在编写程序时仔细检查了一遍。我现在没有收到错误,但是 read() 返回 0
  • 你确定吗?我试过这段代码,read() 返回 3,它必须是。
【解决方案2】:

如果只执行读/写会发生什么?老实说,我不确定 dup 和 cat 是你想要的:

char buf[256];
int len;

len = read(ChildRead, 256);
write(ChildWrite, len);

而且,进一步考虑,如果你知道你想要结束的 fd,使用 dup2,而不是 dup。了解您的 API,人们!

而且,进一步思考,您可以查看 popen(3) 调用的源代码,它以更一般的方式执行此操作。

【讨论】:

  • 我以 cat 为例。我有另一个要调用的子程序。 popen() 也不允许双向通信。
  • @Jeff: popen 正是这样做的,你只需要将它扩展为两个管道,而不是一个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 2012-01-15
  • 2020-04-09
  • 2015-09-27
相关资源
最近更新 更多