使用write()C函数时出现SIGPIPE错误

时间:2019-05-17 17:14:22

标签: c pipe

我真的不知道为什么当我尝试在文件描述符fd2上使用write()时才结束程序。当我使用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 个答案:

答案 0 :(得分:4)

当您尝试写入其读取端已关闭的管道时,会得到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);

}