c - 如何使用管道/excel 最好地构建 4 个进程之间的进程间通信?

标签 c exec fork pipe

我正在尝试设置一个程序,该程序使用进程间通信在使用管道/execl 的四个进程之间进行通信。这是演示管道使用的家庭作业问题的一部分,但我有点难以理解它(即进程树如何增长)。这些进程将成为我系统上二进制文件的实例,因此使用了 execl。为了简要概述我要完成的工作,我想将 stdin 从整个父进程/程序重定向到一个名为“s”的子进程(这是我系统上称为扫描的二进制文件),它解释单词.在“s”/scan 中,它处理来自其标准输入的单词,然后根据单词将单词发送/写入一个进程(“e”)或另一个进程(“o”)。 e/o 进程实际上是相同的二进制文件,只是具有指向它们的符号链接(symbolic link)——它基本上做同样的事情。

我将如何构建我的调用/父程序来构建它?我必须在这个主程序中创建所有进程,否则我只会在 scan/"s"进程中创建两个子进程。我在下面写了一些代码,将主程序的标准输入重定向到“s”进程,但我不确定在哪里 fork 将连接到它的两个子进程。我认为除了“s”/扫描进程之外,最好获取我需要创建的其他两个子进程的 pid,并使用不同的 pid 作为参数调用相应的二进制文件,但我不确定。任何帮助将不胜感激!

 int s_to_e[2]; int s_to_o[2];
 int e_to_s[2]; int o_to_e[2];
 pid_t e_pid; pid_t o_pid; pid_t s_pid;

 if (pipe(s_to_e)) {          
      exit(1);
 }

 if (pipe(s_to_o)) {          
      exit(1);
 }

 if ( (s_pid = fork()) == -1) {
      fprintf(stderr, "Fork error! \n");
      exit(1);
 }

 int status;

 //Child progress of scan
 if (s_pid == 0) {
      //Redirect stdin to s
      //This probably isn't the best way to go about doing this
      dup2(0, s_to_e[0]);
      close(s_to_e[1]);

      //We need to replace the child fork with a new process
      if(execl("./scan", "./scan", NULL ) == -1) {
           printf("execl Error!");
           exit(1);
      }

 } else {
      printf("I am parent\n");
      wait(&status);
      printf("Done\n");
 }  

最佳答案

你的问题有两个错误:

  • I want to redirect stdin from the overall parent process/program to a sub-process

父级的标准输入由子级继承,不会被重定向。

  • I think it would be best to get the pids of the other two sub processes that I need to create in addition to the "s"/scan process and call the respective binaries with the different pids as arguments

不需要将自己的 id 传递给进程;它总是可以通过 getpid() 获取它。

除了错误检查,下面的程序应该能满足你的要求。

#define _GNU_SOURCE
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

main()
{
    int s_to_o[2];  pipe2(s_to_o, O_CLOEXEC);
    int s_to_e[2];  pipe2(s_to_e, O_CLOEXEC);
    if (fork() == 0)
     dup2(s_to_o[1], 1),
     dup2(s_to_e[1], 2), exit(execl("scan", "scan", NULL));
    close(s_to_o[1]);
    close(s_to_e[1]);
    if (fork() == 0)
     dup2(s_to_o[0], 0), exit(execl("o", "o", NULL));
    close(s_to_o[0]);
    if (fork() == 0)
     dup2(s_to_e[0], 0), exit(execl("e", "e", NULL));
    close(s_to_e[0]);
    wait(NULL);
    return 0;
}

关于c - 如何使用管道/excel 最好地构建 4 个进程之间的进程间通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9440892/

相关文章:

c - 使用单循环数组中两个元素之间的最大差异

php - exec 命令适用于终端而不是 PHP

python - python中的多进程会重新初始化全局变量吗?

c - 用于获取和释放PID的API

编译包含 ext2fs.h 的文件

c - 使用 realloc 扩展整数数组会崩溃!

c - Windows Defender/安全性删除我的 “hello world”程序

ruby - 为什么 "bundle exec"会吃掉我传入的参数?

java - 使用 execv 时 Cygwin C 文件返回 "Bad Address"

perl - 如何等待子进程在父进程中设置变量?