Проблемы с получением дочерних процессов для общения друг с другом - PullRequest
0 голосов
/ 28 октября 2019

Я новичок в программировании на Linux. Я пытаюсь создать два дочерних процесса и соединить их через канал. Генерирующий дочерний процесс должен генерировать случайные числа, а другой дочерний процесс должен запускать двоичный файл, который берет эти два числа и находит их наибольший общий делитель. Бинарный файл уже хорошо работает с stdin, поэтому я пытаюсь перенаправить его на чтение конца канала. Точно так же я делаю это с генерацией процесса с подключенным stdout, чтобы записать конец канала.

Но я думаю, что я не очень хорошо справился, соединив его вместе, потому что нет вывода. Любая помощь будет принята с благодарностью!

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

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

#define exec_path "nsd"

void create_pipe(int *proc_pipe);

int create_proc();

void sig_handler(int sig);

int main() {
    int proc_pipe[2];
    pid_t gen_proc;
    pid_t nsd_proc;
    int proc_stat;

    create_pipe(proc_pipe);

    gen_proc = create_proc();

    if (gen_proc == 0) {
        // child exec
        struct sigaction act;
        act.sa_handler = &sig_handler;

        close(proc_pipe[0]);
        dup2(proc_pipe[1], 1);
        close(proc_pipe[1]);

        while (1) {
            printf("%d %d\n", rand() % 4096, rand() % 4096);
            sleep(1);
            if (sigaction(SIGTERM, &act, NULL) == -1) exit(2);
        }
    } else {
        nsd_proc = create_proc();

        if (nsd_proc == 0) {
            // child exec
            close(proc_pipe[1]);
            dup2(proc_pipe[0], 0);
            close(proc_pipe[0]);

            execl(exec_path, "nsd", (char *) NULL);
        } else {
            close(proc_pipe[0]);
            close(proc_pipe[1]);
            sleep(5);
            kill(gen_proc, SIGTERM);
            wait(&proc_stat);
            if (proc_stat != 0) {
                perror("ERROR");
                return 1;
            } else {
                printf("OK\n");
                return 0;
            }
        }
    }
}

void sig_handler(int sig) {
    if (sig == SIGTERM) {
        perror("GEN TERMINATED");
        exit(0);
    }
}

pid_t create_proc() {
    pid_t pid = fork();
    if (pid == -1) {
        perror("error forking new process");
        exit(2);
    }
    return pid;
}

void create_pipe(int *proc_pipe) {
    if (pipe(proc_pipe) == -1) {
        perror("failed to create pipe");
        exit(2);
    }
}

1 Ответ

1 голос
/ 28 октября 2019

printf не вызывает write, пока не заполнит буфер. Вы не даете своему ребенку достаточно времени, чтобы заполнить этот буфер. Добавьте fflush(stdout) перед тем, как ребенок перейдет в режим сна, чтобы некоторые данные фактически были записаны в канал.

...