在 Linux 上使用 C 中的 2 个管道进行双向父子通信
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9318125/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Two-Way Parent Child Communication Using 2 Pipes in C on Linux
提问by Jeff
I'm trying to create a two-way communication between parent and child processes using 2 pipes using C on Linux. The parent is my program and the child is just a random program (say "cat").
我正在尝试在 Linux 上使用 C 使用 2 个管道在父进程和子进程之间创建双向通信。父母是我的程序,孩子只是一个随机程序(比如“猫”)。
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,这是错误的文件描述符。
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, 'dup2 (ChildRead, 0);
dup2 (ChildWrite, 1);
', 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);
}
采纳答案by mikithskegg
If you want to redirect stdin and stdout to pipes, you need to use dup2(2) system call.
如果要将 stdin 和 stdout 重定向到管道,则需要使用 dup2(2) 系统调用。
#define ParentRead read_pipe[0]
#define ParentWrite write_pipe[1]
#define ChildRead write_pipe[0]
#define ChildWrite read_pipe[1]
P.S. Also I found wrong directions of reading/writing in pipes. Here is the correct way
PS我还发现了错误的管道读/写方向。这是正确的方法
execlp("cat", "cat", (char*)NULL);
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. Do not forget to set the first argument you send to the executed programm as a name of the program
还有一个错误,在 execlp 中。不要忘记将发送给执行程序的第一个参数设置为程序名称
char buf[256];
int len;
len = read(ChildRead, 256);
write(ChildWrite, len);
回答by tbert
What happens if you just perform a read/write? I'm unsure that dup and cat are what you want here, to be honest:
如果您只是执行读/写会发生什么?老实说,我不确定 dup 和 cat 是你想要的:
##代码##And, thinking further, if you know the fd you want to end up at, use dup2, not dup. Know your APIs, people!
而且,进一步思考,如果您知道最终要使用的 fd,请使用 dup2,而不是 dup。了解您的 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) 调用的源代码,它以更一般的方式执行此操作。