Аргумент, переходящий из трубы в C - PullRequest
0 голосов
/ 25 августа 2011

Я пытаюсь передать токены через каналы и execvp ... Однако моя проблема в том, что 1-й и 2-й дочерние процессы получают одинаковые токены ... и что можно сделать, если есть третий или более токенов?

    int pipedes[2];
    pipe(pipedes);

    pid_t pid = fork();
    if (pid == 0) {
            dup2(filedes[1], 1);

            execvp(argv[0], argv);
    } else {
            close(pipedes[1]);
    }

    pid = fork();
    if (pid == 0) {
            dup2(pipedes[0], 0);

            execvp(arg[0], argv);
    }

    wait(&pid);

и токены

strtok(line, "|");

            pipe(line);
            while (1) {

                    line= strtok(NULL, "|");

                    pipe(line);
            }

Ответы [ 2 ]

0 голосов
/ 25 августа 2011

Если вы хотите, чтобы два разных дочерних процесса выполняли один и тот же исполняемый файл, но с использованием двух разных команд, вам потребуется настроить два разных канала для каждого дочернего процесса. Процесс настройки труб также неверен, поскольку вы позволяете ребенку оставлять трубу открытой.

#include <sys/wait.h>
#include <unistd.h>
#include <
int pipedes_child_1[2];
int pipedes_child_2[2];

pipe(pipedes_child_1);

pid_t child = fork();

if (!child)
{
    dup2(pipedes_child_1[0], 0);
    close(pipedes_child_1[1]); //without this, child with hang on read()
    execvp(argv[0], argv);
}
else
{
    close(pipedes_child_1[0];
}

pipe(pipedes_child_2);

child = fork();

if (!child)
{
    dup2(pipedes_child_2[0], 0);
    close(pipe_des_child_2[1]);  //without this, child with hang on read()
    execvp(argv[0], argv);
}
else
{
    close(pipedes_child_2[0]);
}

//...write tokens to each child via pipedes_child_X[1];

//wait for all the children
int return_val = 0;
while(wait(&return_val) > 0 || errno != EINTR);

Имейте в виду, что поскольку вы вызываете execvp(argv[0], argv), вы на самом деле собираетесь сделать бесконечно рекурсивный "веер" процессов, поскольку вы просто вызываете текущий процесс с текущими аргументами ... Я не думаю, это то, что вы хотите. Чтобы предотвратить это, допустим, вы задаете дочерние процессы в качестве аргументов основного родительского исполняемого файла и передаете эти значения в качестве программ, запускаемых при вызове одной из функций семейства exec. Так, например:

//child_1 executable that will take no arguments and read from the pipe
execlp(argv[1], argv[1], (char*)0);

//child_2 executable that will take no arguments and read from the pipe
execlp(argv[2], argv[2], (char*)0);
0 голосов
/ 25 августа 2011

Эта строка:

pipe(line);

это ерунда. Он создает два новых файловых дескриптора и перезаписывает первые 2 x sizeof(int) байтов line. Процесс вашего производителя должен записывать токены в stdout, а ваш потребительский процесс должен читать их из stdin.

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

...