管道基础

##管道基础
#通信分类:只写单工管道、只读单工管道、半双工管道(单向读写)、全双工管道(两个半双工管道拼接)
    类型        创建/打开    关闭            读    写
    单工        popen()        pclose()        read()    write()
    半双工        pipe()/open()    close()            read()    write()
    FIFO半双工    mkfifo()/open()    close()/unlink()    read()    write()
    全双工        socketpair()    close()            read()    write()
管道通常用于进程间通信,可以用KFC买东西来比喻,通过man 7 pipe来查看管道在redhat中的官方解释。

#管道的分类
    @匿名管道
        特点:必须是亲缘进程之间
        案例:
            ps_self        \\打印自身的父子进程信息
            ps_other    \\执行参数中的命令,并且打印参数中的命令相关的父子进程
        分类:
            *单工管道
                操作:    管道        文件
                打开    popen()        fopen()
                关闭    pclose()    pclose()
                
            打开管道:FILE* popen(const char* command,const char* open_mode);
                command:命令行字符串
                open_mode:只读"r";只写"w"
                返回值:文件描述符    NULL(打开失败)
            读写:
                size_t fread(void* buffer,size_t size,size_t count,FILE* stream)
                    buffer:用于接收数据的内存地址
                    size:读取每个数据项的字节数
                    count:数据项个数
                    stream:输入流
                    返回值:出错(>count)、整数(实际读取的数据项个数)
                size_t fwrite(const void* buffer,size_t size,size_t count,FILE* stream)
                    buffer:写入数据的内存地址
                    size:写入数据项的字节数
                    count:写入数据项的个数
                    stream:目标文件指针
                    返回值:出错(>count)、正数(实际写入的数据项个数)
            关闭管道:int pclose(FILE* stream);
                stream:文件描述符
                返回值:失败(-1)、成功(0)
            本质:
                a.启动shell和命令两个进程,从命令进程中读/写文件流
                b.解决exec和system无法返回输出数据问题
            特点:
                a.方便使用系统自带功能,并且可以执行比较复杂shell
                b.默认启动两个进程,效率较低

            *半双工管道
                操作:    
                    创建管道:int pipe(int filedes[2])
                        filedes[0]    读
                        filedes[1]    写
                        返回值:失败(-1)、成功(0)
                    读写
                        ssize_t write(int fd,const void* buf,size_t nbyte)
                        fd:文件描述符
                        buf:写入数据的内存单元
                        nbyte:写入文件指定的字节数
                        返回值:出错(-1)、正数(写入的字节数)
                        ssize_t read(int fd,void* buf,size_t count)
                        fd:文件描述符
                        buf:读入数据的内存单元
                        返回值:出错(-1)、0(无数据)、正数(读取的字节数)
                    控制:如果管道是空的,read()默认是阻塞
                        int fcntl(int fd,int cmd,long arg)
                        fd:文件描述符
                        cmd:F_GETFL(获取文件描述符状态)、F_SETFL(设置文件描述符状态)、……
                        arg:O_NONBLOCK(非阻塞)、O_BLOCK(阻塞)、……

                        fcnt(filedes,F_SETFL,O_NONBLOCK);    \\把文件描述符改为非阻塞的。
                        
                    关闭管道:close(filedes)    
                本质:文件描述符[文件流是文件描述符之上的封装。文件流通过增加缓冲区减少读写系统调用次数来提高读写效率。在进程的用户空间封装的FILE结构,以提高可移植性和效率]
            *复制管道
                定义:Linux内核使用三个关联的数据结构,表示打开的文件。【描述符表,文件表,v-node表】内核为每个进程创建的文件文件描述符。
        分类        文件描述符    文件号
        标准输入    STDIN_FILENO    0
        标准输出    STDOUT_FILENO    1
        标准出错信息    STDERR_FILENO    2
                
                int dup(oldfd)    \\返回值:-1(失败)、其他(新的文件描述符)
                int dup2(int oldfd,int newfd)    \\返回值:-1(失败)、其他(最小及尚未使用的文件描述符)
    
    @【半双工】FIFO管道/命名管道
        特点:可以是非亲缘进程之间;读写必须同时执行,否则阻塞。
        案例:FIFO工具箱
        操作:
            创建命名管道:int mkfifo(pathname,mode)【古老方式:int mknod(const char *filename,mode_t mode | S_IFIFO,(dev_t)0);】
                    pathname:文件路径【文件必须不存在】
                    mode:模式
                    返回值:0(成功)、非零(失败)
            打开FIFO文件:int open(const char* path,int mode)
                    pathname:文件路径
                    mode:模式【O_RDONLY(阻塞只读)、O_RDONLY|O_NONBLOCK(非阻塞只读)、O_WRONLY(阻塞只写)、O_WRONLY|O_NONBLOCK(非阻塞只写)】
                    返回值:-1(失败)、其他(文件描述符)


                








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值