管道 重定向 有名管道详解

1、管道:
    (1)、定义:特殊类型的文件,体现为两个文件描述符
    (2)、特点:
        a、半双工,同一时刻数据流向只有一个(父->子、子->父)
        b、数据只能一端写入,一端读出
        c、先入先出
        d、双方要提前约定好数据的格式
        e、没有名字,不存在于文件系统,只存在于内存中
        f、数据是一次性的
        g、有默认大小
        h、只能在有公共祖先的进程间使用
    (3)、函数
        
        pipe: 创建无名管的并获得文件描述符
            int fd[2]={};
            pipe(fd);
        注意:pipe在fork前面,如果pipe在fork后面,那父子进程各自创建了一个无名管道,通信的时候用的就不是同一个无名管道
        
        write、read
        
    (4)、读写特点:
        read:读数据
            带阻塞,如果管道中没有数据,read会阻塞直到管道中有数据为止,会读出数据并返回
        write:写数据
            带阻塞,管道的缓冲区写满了,write就会阻塞
            缓冲区大小:64k
    
        读端口全部关闭(2个),写进程再往里写数据,写进程会推出
        
        
        fcntl:设置文件描述符为非阻塞
            fcntl(fd[0],F_SETFL,O_NONBLOCK);
2、重定向:
    文件描述符的复制:复制一个文件的描述符,使新的文件描述符也标识旧的文件描述符所标识的文件。
    
    fd->a.c,1->stdout
    实现1->a.c
    函数:
        dup:
            close(1);//把1变成最小可用的
            int fd_new = dup(fd);//1去复制fd的指向,1->a.c,fd_new=1
        dup2:
            dup2(fd,1);//注意第二个参数的范围:0-1023
        
    注意:
        1)、0、1、2的指向改变了,原本指向的标准输入、标准输出和标准错误就无法使用,所以需要把标准输入、标准输出和标准错误保存起来
    
        2)、文件描述符在切换的过程中,因为指向的内容可能在stdout和普通文件中来回切换,要注意缓冲区的类型也在变化,所以为了避免缓冲区类型变化而造成的问题,可以选择使用系统调用函数(无缓冲区)
    
3、命名管道
    (1)、定义:特殊类型的文件,存在于文件系统中
    (2)、特点:
            a、半双工,同一时刻数据的流向只有一个
            b、先入先出
            c、没有格式要求,要双方实现约定好
            d、有名字,在文件系统中可以查看到,但是内容存在于内存中
            e、数据时一次性的
            f、对应缓冲区,有固定大小
            g、创建过一次,以后就无需创建,可直接使用
            h、可以实现不相关进程的通信
        注意:如果进行复制,管道文件会变成普通文件,所以要注意,复制后的管道文件要进行删除并重新创建    
    (3)、函数:
        mkfifo("./fifo",0777);
        文件类型: p 管道文件
        open:打开方式:已存在的方式,不能加O_CREAT
        read、write
        注意:命名管道的内容存在于内存中,如果进程结束,内存释放,命名管道中的内容也就没有了,使用的时候要注意,写进程的存活
    (4)、读写特点:
        1)、O_RDWR:
            a、read是带阻塞的,有内容就读,没有内容就阻塞在这,直到命名管道中有数据为止
            b、write是带阻塞的,缓冲区写满了,write就阻塞
        2)、只读或只写(不位或O_NONBLOCK)
            a、以只读或只写的方式打开命名管道,open会阻塞,直到其他进程以写或读的方式打开命名管道为止(open_read.c open_write.c)
            b、read是带阻塞的
            c、write是带阻塞的
            d、写进程退出,read变为非阻塞;写进程再运行,read会恢复为阻塞(write_4.c read_4.c)
            e、读进程退出,写进程再往命名管道中写数据,写进程也会退出(write_4.c read_4.c)
        3)、只读或只写(位或O_NONBLOCK)
            a、open:以只写方式并位或O_NONBLOCK打开命名管道,且没有任何进程以读的方式打开命名管道,会失败(non_write_open.c)
            b、open:以只读方式并位或O_NONBLOCK打开命名管道,会成功(non_read_open.c)
            c、write和read是非阻塞的
            d、读进程退出后,写进程再向命名管道中写数据,写进程也会退出(non_read_open.c non_write_open.c)
           

猜你喜欢

转载自blog.csdn.net/lyw13522476337/article/details/80823853