Как лучше всего структурировать межпроцессное взаимодействие между 4 процессами с помощью pipe / execl? - PullRequest
1 голос
/ 25 февраля 2012

Я пытаюсь настроить программу, которая использует межпроцессное взаимодействие для связи между четырьмя процессами, используя pipe / execl.Это часть домашней работы, чтобы продемонстрировать использование каналов, но у меня возникли некоторые трудности, когда я оборачиваюсь вокруг нее (то есть, как растет дерево процессов).Эти процессы должны быть экземплярами двоичных файлов в моей системе, следовательно, использование execl.Чтобы дать краткий обзор того, что я пытаюсь выполнить, я хочу перенаправить стандартный ввод из общего родительского процесса / программы в подпроцесс, называемый «s» (который является двоичным в моей системе, называемый сканированием), который интерпретирует слова,В «s» / scan он обрабатывает слова из своего стандартного ввода, а затем, в зависимости от слова, отправляет / записывает слово либо одному процессу («e»), либо другому процессу («o»).Процессы ввода / вывода на самом деле являются одним и тем же двоичным файлом, который просто имеет символические ссылки на них - он в основном делает то же самое.

Как бы я структурировал свою вызывающую / родительскую программу, чтобы структурировать это?Мне нужно создать все процессы в этой основной программе, иначе я бы просто создал два подпроцесса в процессе сканирования / s.Ниже приведен код, который я написал для перенаправления стандартного ввода основной программы в процесс "s", но я не уверен, куда нужно форкировать два подпроцесса, которые будут к нему подключаться.Я думаю, что было бы лучше получить pid двух других подпроцессов, которые мне нужно создать в дополнение к процессу "s" / scan, и вызвать в качестве аргументов соответствующие двоичные файлы с разными pids, но я не уверен.Любая помощь будет высоко ценится!

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

Ответы [ 2 ]

1 голос
/ 14 марта 2014

Две ошибки в вашем вопросе:

  • Я хочу перенаправить стандартный ввод из общего родительского процесса / программы в подпроцесс

Стандартный ввод родительского объекта наследуется дочерним элементом и не должен перенаправляться.

  • Я думаю, что было бы лучше получить пидс двух других суб процессы, которые мне нужно создать в дополнение к процессу "s" / scan и вызвать соответствующие двоичные файлы с различными pids в качестве аргументов

Нет необходимости передавать свой собственный идентификатор процессу; он всегда может получить его по 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;
}
0 голосов
/ 25 февраля 2012

Вы можете установить динамическую переменную для передачи номера текущего процесса и использовать неблокированный ввод-вывод для считывания значения, которое будет записано родительским объектом в канал.

Это означает, что после разветвленияпроцессы должны делать следующее:

  1. эхо-процесс закрывает бесполезный канал.
  2. parent, чтобы прочитать значение (если не удалось, установите его в 0).
  3. родительская записьувеличенное значение в трубе.
  4. дочерний элемент execl к той же программе.

Тогда все должно быть в порядке.

...