在C语言中,如何在父进程和子进程之间相互发送数据?

4

我已经编写了一个程序,创建了5个管道并在循环中fork了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读取数据,从父进程发送到管道的数据。就像这样(program.c):

char *buffer = (char *)malloc(50);
read(STDIN_FILENO, buffer, 50);

我的问题是,如何将数据发送回父进程?我想使用dup2再次替换stdout以使用管道输出,但我无法使其正常工作。我意识到这至少在使用execv(...)之前必须完成。
我不确定是否已经足够解释清楚了,所以我可以制作一个带有文本的小图像:) 现在的情况是这样的:
  • 父进程 -> 管道
  • 管道 -> 子进程1
  • 管道 -> 子进程2
  • 管道 -> ...
  • 管道 -> 子进程5
我想要的是这样的:
  • 父进程 -> 管道
  • 管道 -> 子进程1
  • 管道 -> 子进程2
  • 管道 -> ...
  • 管道 -> 子进程5
  • 子进程1 -> 父进程
  • 子进程2 -> 父进程
  • ...
  • 子进程5 -> 父进程

感谢帮助!
4个回答

4
管道是单向的,不是双向的,所以一个通用的解决方案是创建五个额外的管道(呃!)来返回数据。然后父进程需要使用 select() 系统调用来知道哪个返回管道有准备好读取的数据。
哦,我会写成
    dup2(fd[0], 0); // 用管道输入替换标准输入
应该是
    dup2(fd[0], 0); // 用管道输出替换标准输入
反之亦然。
就像其他回复所说,根据您要实现的目标,可能有其他更合适的通信方法。

2

请看这里的Unix编程FAQ,查看问题1.5,也许可以使用内存映射来允许父/子进程在两端进行读/写操作......这里有一份优秀的IPC理解指南


0
我在网上搜索了一下。看起来你只能使用管道进行单向通信。这是有道理的 - 从标准输入读取并输出到标准输出。如果您想要在父子进程之间实现双向通信,请使用套接字。还有其他方法可以实现双向进程间通信。建议您学习更多关于进程间通信的知识。
祝一切顺利。

0

如果你想继续使用管道,那么为子进程到父进程的通信和父进程到子进程的通信分别创建一组文件描述符。所以,不要使用 int fd[2],而是使用 int toParent[2] 和 toChild[2]。不要使用 dup2(fd[0], 0),而是使用 dup2(toChild[0], 0); dup2(toParent[1], 1)。

并且不仅要复制,还要关闭你不再使用的文件描述符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接