Я получаю ошибку SIGPIPE при использовании функции write () C - PullRequest
0 голосов
/ 17 мая 2019

Я действительно не знаю, почему, когда я пытаюсь использовать write () для файлового дескриптора fd2, это просто завершает программу.Когда я использую valgrind, я получаю «Процесс завершается с действием по умолчанию сигнала 13 (SIGPIPE)».Проблемная строка: write (fd2 [1], & num, sizeof (num));

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

/*
 * Ejemplo de codigo que genera un numero aleatorio y lo muestra por pantalla
 */
#include <sys/types.h>
#include <sys/wait.h>

 #include <time.h>
 #include <stdlib.h>
 #include <stdio.h>
#include <unistd.h>



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

    int pid1,pid2,fd1[2],fd2[2],pipe_status1,pipe_status2;

    pipe_status1=pipe(fd1);
    if(pipe_status1 == -1) {
        perror("Error creando la tuberia 1\n");
        exit(EXIT_FAILURE);
    }
    pipe_status2=pipe(fd2);
    if(pipe_status2 == -1) {
        perror("Error creando la tuberia 2\n");
        exit(EXIT_FAILURE);
    }

    pid1 = fork();
    if (pid1 <  0  )
    {
        printf("Error al emplear fork\n");
        exit (EXIT_FAILURE);
    }
    else  if(pid1 ==  0)
    {
            /* Inicializa el generador con una semilla cualquiera, OJO! este metodo solo
        se llama una vez */
        srand(time(NULL));
        /* Devuelve un numero aleatorio en 0 y MAX_RAND(un número alto que varia
        segun el sistema) */
        int r = rand();
        printf("El numero aleatorio es %d\n", r);

        close(fd1[0]);
        write(fd1[1], &r, sizeof(r));

        exit(EXIT_SUCCESS);
    }

    wait(NULL);
    int num;
    close(fd1[1]);
    read(fd1[0], &num, sizeof(num));
    printf("He recibido el numero: %d\n", num);


    close(fd2[0]);

    write(fd2[1], &num, sizeof(num));




    pid2 = fork();
        if (pid2 <  0  )
    {
        printf("Error al emplear fork\n");
        exit (EXIT_FAILURE);
    }
    else  if(pid2 ==  0)
    {
        close(fd2[1]);
        read(fd2[0], &num, sizeof(num));
        printf("He recibido el numero: %d\n", num);
    }

    wait(NULL);

    exit(EXIT_SUCCESS);

}

1 Ответ

4 голосов
/ 17 мая 2019

Вы получаете SIGPIPE при попытке записи в канал, конец чтения которого был закрыт.Так как вы делаете close(fd2[0]); в строке до этого, именно поэтому вы получаете ошибку.

Вам нужно создать второго потомка, прежде чем вы введете close(fd2[0]); в родительском.Ребенок унаследует трубу, и это держит ее открытой.

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

Измените вторую часть вашего кода на:

    pid2 = fork();
    if (pid2 <  0  )
    {
        printf("Error al emplear fork\n");
        exit (EXIT_FAILURE);
    }
    else  if(pid2 ==  0)
    {
        close(fd2[1]);
        read(fd2[0], &num, sizeof(num));
        printf("He recibido el numero: %d\n", num);
        exit(EXIT_SUCCESS);
    }
    close(fd2[0]);
    write(fd2[1], &num, sizeof(num));

    wait(NULL);

    exit(EXIT_SUCCESS);

}
...