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

Ver*_*rkr 0 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);

}
Run Code Online (Sandbox Code Playgroud)

Bar*_*mar 5

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);

}
Run Code Online (Sandbox Code Playgroud)