在 C 中从父进程向子进程发送数据,反之亦然
我编写了一个程序,在循环中创建 5 个管道并分叉 5 个进程。当每个子进程与另一个程序重叠时,我已设法将数据从父进程发送到每个子进程。每个循环都按以下方式完成
(parent.c):
// Child process - reads from pipe
if (childpid == 0) {
dup2(fd[0], 0); // replace stdin with pipe input
execv("program", arguments);
} else { // Parent process - writes to pipe
write(fd[1], buffer, strlen(buffer)+1);
}
所以现在我可以通过从程序中的 STDIN_FILENO 读取子级来获取从父级发送到管道的数据使用 execv(...) 执行。
像这样(program.c):
char *buffer = (char *)malloc(50);
read(STDIN_FILENO, buffer, 50);
但是我的问题是,如何将数据发送回父级?我正在考虑再次使用 dup2 将 stdout 替换为管道输出,但我无法让它工作。我意识到这至少必须在使用 execv(...) 之前完成。
我不确定这个解释是否足够,所以我可以用文字制作一个小图像:)
现在就是这样:
- 父 ->管道
- 管道->子进程1
- 管道->子进程2
- 管道-> ...
- 管->子进程 5
我希望它是这样的。
- 父进程 ->管道
- 管道->子进程1
- 管道->子进程2
- 管道-> ...
- 管->子进程 5
- 子进程 1 ->父子
- 进程2->父
- 进程...
- 子进程5->家长
感谢帮助!
I've made a program that create 5 pipes and fork 5 processes in a loop. I've managed to send data from the parent to each child processe, when each child processe is overlapped by another program. Each loop is done in the following manner
(parent.c):
// Child process - reads from pipe
if (childpid == 0) {
dup2(fd[0], 0); // replace stdin with pipe input
execv("program", arguments);
} else { // Parent process - writes to pipe
write(fd[1], buffer, strlen(buffer)+1);
}
So now i'm able to get the data that is sent from the parent to the pipe, by reading from STDIN_FILENO in the program the childs executes with execv(...).
Like this (program.c):
char *buffer = (char *)malloc(50);
read(STDIN_FILENO, buffer, 50);
My problem however is, how can I send data back to the parent? I was thinking of something like replacing stdout with the pipe output by using dup2 again, but I can't get it to work. I realise this have to be done before using execv(...) at least.
I'm not sure if that explanation was sufficient so I can make a little image with text : )
This is how it is right now:
- Parent -> Pipe
- Pipe -> Child process 1
- Pipe -> Child process 2
- Pipe -> ...
- Pipe -> Child process 5
I want it to be like this.
- Parent -> Pipe
- Pipe -> Child process 1
- Pipe -> Child process 2
- Pipe -> ...
- Pipe -> Child process 5
- Child process 1 -> Parent
- Child process 2 -> Parent
- ...
- Child process 5 -> Parent
Thankful for help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
管道是单向的,而不是双向的,因此通用解决方案是为返回数据创建另外五个管道(gak!)。然后,父级需要使用
select()
系统调用来了解哪个返回管道有可供读取的数据。哦,我会写
should be
and vice versa.
就像其他回复所说,还有其他沟通方法可能更合适,具体取决于您想要实现的目标。
Pipes are unidirectional, not bidirectional, so a generic solution is to create five more pipes (gak!) for the return data. The parent then needs to use
select()
system call to know which of the return pipes have data ready for reading.Oh, and I would have written
should be
and vice versa.
Like the other replies say, there are other communication methods that may be more appropriate, depending on what you are trying to achieve.
请参阅此 unix 编程常见问题解答,查看问题 1.5 ,也许使用内存映射来允许父/子进程从两端读取/写入...有一个很好的指南来理解 IPC 此处。
See this unix programming faq here, look at question 1.5, maybe using a memory map to allow the parent/child processes to read/write from on both ends...There is an excellent guide to understanding IPC here.
我在网上查了一下。似乎只能使用管道来以一种方式进行通信。这是有道理的 - 从标准输入输入并输出到标准输出。如果您想在父进程和子进程之间进行双向通信,请使用套接字。还有其他方法可以实现双向IPC。我建议你更多地了解进程间通信。
一切顺利。
I looked around on the internet for a bit. It seems that you can use pipes only to communicate one way. Which makes sense - input from stdin and output to stdout. If you want to have two way communication between your parent and child processes, use sockets. There are other methods to achieve two way IPC. I suggest that you learn more about inter process communication.
All the best.
如果你想继续使用管道,那么创建一组FD用于子->父通信,一组FD用于父->子通信。因此,您拥有的不是 int fd[2],而是 int toParent[2]、toChild[2]。你有 dup2(toChild[0], 0); 而不是 dup2(fd[0], 0); dup2(toParent[1], 1).
并且不要只是复制,而是关闭不使用的 FD。
If you want to keep using pipes, then make one group of FDs for child->parent communication and one for parent->child communication. So instead of having int fd[2], you have int toParent[2], toChild[2]. Instead of dup2(fd[0], 0), you have dup2(toChild[0], 0); dup2(toParent[1], 1).
And don't just dup, but close the FDs you aren't using.