2010-01-31 2 views
2

Я создал программу, которая создает 5 циклов и вилки 5 процессов в цикле. Мне удалось отправить данные от родителя к каждому дочернему процессу, когда каждый дочерний процесс перекрывается другой программой. Каждый цикл выполняется следующим образомОтправка данных от родительского к дочернему процессу и наоборот в C

(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 в программе выполняет childs с execv (...).

Как это (program.c):

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

Моя проблема, однако, в том, как я могу отправить данные обратно к родителю? Я думал о чем-то вроде замены stdout на выход трубы с помощью dup2 снова, но я не могу заставить его работать. Я понимаю, что это нужно сделать, прежде чем использовать execv (...) по крайней мере.


Я не уверен, если это объяснение было достаточно, чтобы я мог сделать маленький файл с текстом:)

Это, как это прямо сейчас:

  • Родитель - > Труба
  • трубы -> процесс по уходу за детьми 1
  • трубы -> процесс по уходу за детьми 2
  • Pipe -> ...
  • Pipe -> Процесс по уходу за детьми 5

Я хочу, чтобы это было так.

  • Родитель -> Труба
  • Pipe -> Процесс по уходу за детьми 1
  • Pipe -> Процесс по уходу за детьми 2
  • Pipe -> ...
  • Pipe -> Процесс по уходу за детьми 5
  • Детский процесс 1 -> Родитель
  • Детский процесс 2 -> Родитель
  • ...
  • процесс по уходу за детьми 5 -> Родитель

Благодарен за помощь!

ответ

0

Я немного поглядел в Интернете. Кажется, что вы можете использовать каналы только для общения одним способом. Что имеет смысл - ввод из stdin и вывода в stdout. Если вы хотите иметь двухстороннюю связь между родительским и дочерним процессами, используйте сокеты. Существуют и другие способы достижения двухстороннего IPC. Я предлагаю вам больше узнать о взаимодействии между процессами.

Все самое лучшее.

2

Смотрите эту unix programming faq здесь, посмотрите на вопрос 1,4 1.5, возможно, используя карту памяти, чтобы позволить родительский/дочерний процессы чтения/записи с обоих концов ... Существует отличное руководство к пониманию IPC here.

Edit: Благодаря Тренту для указывая на небольшой всплеск в опечатке ... Я имел в виду 1,5 ...

Надеется, что это помогает, С наилучшими пожеланиями, Том.

+0

Вы имеете в виду вопрос 1.5? – Trent

+0

@Trent: Упс, да, я имел в виду 1.5 ... извините .... отредактирует это соответственно ... спасибо за указание. – t0mm13b

3

Трубы однонаправленные, не двунаправленные, поэтому общим решением является создание еще пяти труб (gak!) Для возвращаемых данных. Затем родитель должен использовать системный вызов select(), чтобы узнать, какие из возвратных каналов имеют данные, готовые для чтения.

Да, и я бы написал

 
    dup2(fd[0], 0); // replace stdin with pipe input 
должны быть
 
    dup2(fd[0], 0); // replace stdin with output from pipe 
и наоборот.

Как и в других ответах, существуют другие способы коммуникации, которые могут быть более подходящими, в зависимости от того, чего вы пытаетесь достичь.

0

Если вы хотите продолжать использовать каналы, то создайте одну группу из FD для родительской связи child-> parent и одну для родительской - дочерней связи. Поэтому вместо того, чтобы иметь int fd [2], у вас есть int toParent [2], toChild [2]. Вместо dup2 (fd [0], 0) у вас есть dup2 (toChild [0], 0); dup2 (toParent [1], 1).

И не просто дублируйте, а закрывайте FD, которые вы не используете.

Смежные вопросы