Linux上C中使用2个管道的双向父子通信

Linux上C中使用2个管道的双向父子通信,c,linux,process,communication,pipe,C,Linux,Process,Communication,Pipe,我正在尝试在Linux上使用2个使用C的管道在父进程和子进程之间创建双向通信。家长是我的程序,孩子只是一个随机程序(比如说“猫”) 我尝试在父级中使用read()来读取子级输出,但它给出了错误9,这是一个错误的文件描述符 下面是我的代码 #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #d

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

我尝试在父级中使用
read()
来读取子级输出,但它给出了错误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);
}
#包括
#包括
#包括
#包括
#包括
#定义读取0
#定义写入1
#定义ParentRead\u管道[1]
#定义ParentWrite写入管道[0]
#定义子读写管道[1]
#定义子写入读取管道[0]
int main()
{
已处理的int数据;
/**用于读取子流程的管道*/
int read_管道[2];
/**用于写入子进程的管道*/
int-write_管道[2];
字符缓冲区[100];
内存集(缓冲区,'\0',100);
if(管道(读取管道)==0和管道(写入管道)==0)
{
pid_t pid=fork();
如果(pid==(pid_t)-1)
{
fprintf(标准“叉故障”);
退出(退出失败);
}
else if(pid==(pid\u t)0)//子进程
{
关闭(读取);
关闭(写入);
关闭(ParentRead);
关闭(ParentWrite);
dup(儿童阅读);
dup(ChildWrite);
execlp(“cat”,(char*)空值;
退出(退出失败);
}
else{//父进程
关闭(儿童阅读);
关闭(ChildWrite);
写(家长写,“abc”,3);
int r=read(ParentRead,buffer,99);
printf(“%d%d”,r,errno);
放置(缓冲);
}
}
退出(退出成功);
}

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

char buf[256];
int len;

len = read(ChildRead, 256);
write(ChildWrite, len);
而且,进一步考虑,如果您知道要结束的fd,请使用dup2,而不是dup。了解你的API,朋友们


而且,进一步考虑,您可以更一般地查看popen(3)调用的源代码,它正是这样做的。

如果您想将stdin和stdout重定向到管道,则需要使用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]
记住:管道[0]是用于读取的fd,管道[1]是用于写入的fd

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

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

在执行I/O之前打开()管道。管道(读取管道)==0和管道(写入管道)==0)与打开管道不一样吗?我以cat为例。我想调用另一个子程序。另外,popen()不允许双向通信。@杰夫:popen正是这样做的,您只需要将它扩展到两个管道,而不是一个管道。我将所有dup()更改为dup2(),但仍然得到相同的结果。read()返回-1,错误号为9。我怎么会这么粗心。我甚至在编写程序时仔细检查了一下。我现在没有收到错误,但是read()返回0。您确定吗?我尝试了这段代码,read()返回3,这是必须的。