简体   繁体   English

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

[英]Two-Way Parent Child Communication Using 2 Pipes in C on Linux

I'm trying to create a two-way communication between parent and child processes using 2 pipes using C on Linux. 我正在尝试使用Linux上的C使用2个管道在父进程和子进程之间创建双向通信。 The parent is my program and the child is just a random program (say "cat"). 父母是我的计划,孩子只是一个随机程序(比如“猫”)。

I try to uses read() in parent to read child output, but it gives me errno 9, which is Bad file descriptor. 我尝试在父级中使用read()来读取子输出,但是它给了我errno 9,这是Bad文件描述符。

The following is my code 以下是我的代码

#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);
}

If you want to redirect stdin and stdout to pipes, you need to use dup2(2) system call. 如果要将stdin和stdout重定向到管道,则需要使用dup2(2)系统调用。

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

PS Also I found wrong directions of reading/writing in pipes. PS我也发现错误的读/写管道方向。 Here is the correct way 这是正确的方法

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

Remember: pipe[0] is fd for reading, pipe[1] is fd for writing. 记住:pipe [0]是fd用于读取,pipe [1]是fd用于写入。

And one more error, in execlp. 还有一个错误,在execlp中。 Do not forget to set the first argument you send to the executed programm as a name of the program 不要忘记将发送到执行程序的第一个参数设置为程序名称

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

What happens if you just perform a read/write? 如果你只是执行读/写会发生什么? I'm unsure that dup and cat are what you want here, to be honest: 老实说,我不确定在这里你想要的是什么和猫?

char buf[256];
int len;

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

And, thinking further, if you know the fd you want to end up at, use dup2, not dup. 而且,进一步思考,如果你知道你想要最终的fd,使用dup2,而不是dup。 Know your APIs, people! 知道你的API,人!

And, thinking even further, you could look at the source for the popen(3) call, which does exactly this, in a more general way. 并且,进一步思考,你可以以更一般的方式查看popen(3)调用的源代码,这正是这样做的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM