Трубы между дядей и племянником - PullRequest
0 голосов
/ 23 мая 2018

Итак, у меня есть следующий код

const int CMAX = 1048578;

int main(int argc, char *argv[]){
    int fd[2];
    pid_t v1, v2, v3, a;
    if( pipe( fd ) == -1 ){
        puts("Failed to create pipe !\n" );
        return 1;
    }
    v1 = fork();
    if(v1 == 0){
        close(fd[0]);
        write(fd[1], "hello", CMAX);
        printf("v1      Parent's PID = %ld; Process' PID = %ld\n", getppid(), getpid());
    }
    if(v1 > 0){
        v2 = fork();
        if(v2 == 0){    
            printf("v2      Parent's PID = %ld; Process' PID = %ld\n", getppid(), getpid());
        }
        if(v2 > 0){
            v3 = fork();
            if(v3 == 0){
                printf("v3      Parent's PID = %ld; Process' PID = %ld\n", getppid(), getpid());
                a = fork();
                if(a == 0){
                    printf("a       Parent's PID = %ld;  Child's PID = %ld\n", getppid(), getpid());
                    close(fd[1]);
                    char buf[CMAX];
                    int bytes = read(fd[0], buf, CMAX);
                    printf("Message: %s\nSize: %d", buf, bytes);
                    }
                }
            }
    }
    return 0;
}

Он выводит следующий текст:

v2      Parent's PID = 23859; Process' PID = 23861
v1      Parent's PID = 23859; Process' PID = 23860
v3      Parent's PID = 23859; Process' PID = 23862
a       Parent's PID = 23862;  Child's PID = 23863
Message: 
Size: 0

Я хочу отправить сообщение (или любые данные) из v1 процесс к a процессу.Я предполагаю, что я должен закрыть трубы в других процессах, но не уверен, как.Я пытался закрыть их в каждом процессе, но безуспешно (возможно, я закрыл их неправильно).

Ответы [ 2 ]

0 голосов
/ 24 мая 2018

Я хочу отправить сообщение (или любые данные) из процесса v1 в процесс.Я полагаю, что я должен закрыть каналы в других процессах, но не знаю, как.

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

Однако я не уверен, что вы подразумеваете под «не уверен как».Ваш код демонстрирует, что вы знаете, как использовать close(), и что вы знаете, как использовать возвращаемое значение fork(), чтобы различать родительский и дочерний процессы.Единственное другое - это время: убедитесь, что каждый процесс закрывает любые файловые дескрипторы, которые он собирается закрыть, только после разветвления всех дочерних элементов, которым нужно получить свои собственные открытые копии.

Я пытался закрыть их в каждом процессено не удалось (возможно, я их неправильно закрыл).

Похоже, у вас есть некоторые неправильные представления о read() и write().В частности,

  • это низкоуровневые функции, и они ничего не знают о строках.Когда вы write(), то вы должны точно указать количество байтов, которое вы хотите записать.Вы не можете ожидать, что запись остановится на ограничителе строки.Точно так же, когда вы read(), вы должны указать максимальное количество байтов, которые вы хотите получить, и хотя вы можете передавать терминатор строки по каналу, read() не предоставит его автоматически, если вы не 'т.

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

Имея это в виду, если я исправлю вашу программу для записи и чтения точно 6 байтов,тогда этого достаточно для получения ожидаемого результата для меня.Однако это по-прежнему оставляет некоторые потенциальные проблемы, связанные с размерами передачи (короткие записи и короткие чтения не защищены).

0 голосов
/ 24 мая 2018

Как заметил aschepler , я записал слишком много байтов в свой буфер.Таким образом, правильная версия будет write(fd[1], "hello", 6); (или любое разумное значение).

...