Leer y escribir características de la tubería y configurarla para que no se bloquee.

Las características de lectura y escritura de las tuberías:


Al utilizar una tubería, debe prestar atención (bloqueo predeterminado de operaciones de E/S)
1. Todos los descriptores de archivos que apuntan al extremo de escritura de la tubería están cerrados (el recuento de referencias del extremo de escritura de la tubería es 0), y allí es un proceso que lee datos desde el extremo de lectura de la tubería, luego la tubería Después de leer los datos restantes,
la lectura nuevamente devolverá 0, al igual que leer hasta el final del archivo;

2. Si el descriptor de archivo que apunta al extremo de escritura de la tubería no está cerrado (el recuento de referencias del extremo de escritura de la tubería es mayor que 0) y el proceso que sostiene el extremo de escritura de la tubería no escribe datos en la tubería, en este momento hay un proceso de lectura de datos de la tubería.
Luego, después de leer los datos restantes en la tubería, la lectura se bloqueará nuevamente. Los datos no se leerán ni se devolverán hasta que haya datos en la tubería que se puedan leer;

3. Si todos los descriptores de archivo que apuntan al extremo de lectura de la tubería están cerrados (el recuento de referencias del extremo de lectura de la tubería es 0) y un proceso escribe datos en la tubería en este momento, el proceso recibirá una señal SIGPIPE, lo que generalmente resulta en una excepción del proceso.

4. Si el descriptor de archivo que apunta al extremo de lectura de la tubería no está cerrado (el recuento de referencias del extremo de lectura de la tubería es mayor que 0) y el proceso que sostiene el extremo de lectura de la tubería no lee datos del tubería, y un proceso escribe datos en la tubería,
luego, cuando la tubería está llena, la escritura nuevamente se bloqueará hasta que haya una posición vacía en la tubería antes de que los datos se puedan escribir nuevamente y devolver.

Resumen de
    la canalización de lectura:
        hay datos en la canalización y la lectura devuelve el número real de bytes leídos.
        No hay datos en la canalización:
            el extremo de escritura está completamente cerrado, la lectura devuelve 0 (equivalente a leer el final del archivo) ,
            el extremo de escritura no está completamente cerrado y la lectura se bloquea y espera
    la escritura Tubería:
        todos los extremos de lectura de la tubería están cerrados y el proceso finaliza de manera anormal (el proceso recibe la señal SIGPIPE).
        No todos los extremos de lectura de la tubería están cerrados:
            el la tubería está llena, escribe bloques,
            la tubería no está llena, escribe escribe los datos y devuelve los bytes realmente escritos.

Configure la tubería para que no se bloquee

//子进程发送数据给父进程,父进程读取到数据输出
#include <unistd.h>
#include<sys/types.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<fcntl.h>
/*
设置管道非阻塞
fcntl(fd[0], F_GETFL) //获取原来的flag
flags |= O_NONBLOCK //修改flag
fcntl(fd[0], F_SETFL, flags); //设置新的flag
*/
int main() {
    //在fork之前创建管道
    int pipefd[2];
    int ret = pipe(pipefd);
    if(ret == -1) {
        perror("pipe");
        exit(0);
    }
    //创建子进程
    pid_t pid = fork();
    if(pid > 0) {
        //父进程
        //从管道读取端读取数据
        printf("i am parent process, pid: %d\n", getpid());
        int flags = fcntl(pipefd[0], F_GETFL);
        flags |= O_NONBLOCK;
        fcntl(pipefd[0], F_SETFL, flags);
        //关闭写端
        close(pipefd[1]);
        char buf[1024] = {0};
        while(1) {
            //在管道中读取数据
            int len = read(pipefd[0], buf, sizeof(buf));
            printf("len : %d\n", len);
            printf("parent recv : %s, pid: %d\n", buf, getpid());
            memset(buf, 0, 1024);
            sleep(1);
        }
    } else if(pid == 0){
        //子进程
        printf("i am child process, pid: %d\n", getpid());
        //关闭读端
        close(pipefd[0]);
        char buf[1024] = {0};
        while(1) {
            //在管道中写入数据
            char * str = "hello, i am child";
            write(pipefd[1], str, strlen(str));
            sleep(5);
        }
    }
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/ME_Liao_2022/article/details/133176391
Recomendado
Clasificación