Pipe, Fork и Exec - двусторонняя связь между родительским и дочерним процессами

Присвоение в моем классе операционных систем требует от меня построения двоичного дерева процессов путем рекурсивного вызова exec для той же программы. Цель состоит в том, чтобы разделить произвольную задачу на отдельные процессы. Родитель должен общаться с детьми, а дети - с родителями только через неназванные каналы. Идея состоит в том, что родитель отправляет каждому дочернему элементу половину работы, и это продолжается рекурсивно, пока не будет достигнут базовый случай, где длина строки, передаваемой каждому дочернему элементу, составляет <= 2. Затем дочерний процесс обрабатывает эти данные и отправляет результаты родителю через каналы.

Чтобы лучше понять, как работает двусторонняя связь с каналами в c, я создал следующую простую программу, прежде чем перейти к реальному назначению. Родитель никогда не читает данные из дочернего процесса. Я'м ожидая выхода ...

в родительском | сообщение получено: тест

Вместо этого, когда я печатаю, я получаю ...

в родительском | сообщение доставлено:

Кажется, что бафф пуст и не читает от дочернего процесса. Может кто-нибудь объяснить, пожалуйста, что яЯ делаю неправильно и / или стандартный способ

писать exec 'д ребенок от родителячтение от родителя в exec 'д ребенокпереписывание с родителем из exec 'д ребенокчтение из exec 'd ребенок в родителе

Я обязан использовать exec (), pipe (), fork (). Спасибо.

/**
 * *********************************
 * two_way_pipes.c
 * *********************************
 */

#include 
#include 
#include 
#include 
#include 
#include  
#include  
#include 

#define PARENT_READ read_pipe[0]
#define PARENT_WRITE write_pipe[1]
#define CHILD_WRITE read_pipe[1]
#define CHILD_READ  write_pipe[0]

#define DEBUGGING 1

int main(int argc, char **argv) {
    char buff[5];

    // in the child process that was exec'd on the orginal call to two_way_pipes
    if(argc == 2) {
        read(STDIN_FILENO, buff, 4); // this should read "test" from stdin
        buff[4] = '\0';
        fprintf(stdout, "%s\n", buff); // this should right "test" to stdout and be read by the parent process
    // int the root process, the original call to two_way_pipes with no args
    } else {
        int pid;
        int read_pipe[2];
        int write_pipe[2];

        pipe(read_pipe);
        pipe(write_pipe);

        pid = fork();

        // parent process
        if(pid > 0) {
            close(CHILD_READ);
            close(CHILD_WRITE);

            write(PARENT_WRITE, "test", 4); // attempting to write this to the child

            struct timeval tv;
            fd_set readfds;
            tv.tv_sec = 10;
            tv.tv_usec = 0;
            FD_ZERO(&readfds);
            FD_SET(PARENT_READ, &readfds);
            select(PARENT_READ + 1, &readfds, NULL, NULL, &tv);

            if(FD_ISSET(PARENT_READ, &readfds)) {
                read(PARENT_READ, buff, 4); // should read "test" which was written by the child to stdout
                buff[4] = '\0';
                close(PARENT_READ);
                close(PARENT_WRITE);
                fprintf(stderr, "in parent | message received: %s\n", buff);  // "test" is not in buff
            }

        // child process
        } else if(pid == 0) {
            close(PARENT_READ);
            close(PARENT_WRITE);

            dup2(CHILD_READ, STDIN_FILENO);
            dup2(CHILD_WRITE, STDOUT_FILENO);
            close(CHILD_READ);
            close(CHILD_WRITE);

            char *argv2[] = {"some random arg to make sure that argc == 2 in the child", NULL};
            execvp("two_way_pipes", argv2);
            _exit(0);
        // error forking child process
        } else {
            fprintf(stderr, "error forking the child\n");
        }
    }
}

Обновить

По мотивам Джонатонаответ я изменил массив arg2, передаваемый в execvp, чтобы ...

char *argv2[] = {"two_way_pipes", "1", NULL};
execvp("two_way_pipes", argv2);

Это неисправить проблему. Родитель еще не былне умею читатьтестовое задание" назад от клиента. Тем не менее, в ответ на Джонатонас ответом УильямаКомментарий Я начал настраивать свой exec-вызов и по какой-то причине изменил его на показанную ниже строку.

execl("two_way_pipes", "two_way_pipes", "1", NULL);

Я с радостью приму любые ответы, объясняющие, почему вызов execvp нет работает, но вызов execl сработал.

Ответы на вопрос(3)

Ваш ответ на вопрос