Linux 管道通信

pipe管道

实现原理: 内核借助环形队列机制,使用内核缓冲区实现。

特质: 1. 伪文件

2. 管道中的数据只能一次读取。

3. 数据在管道中,只能单向流动。

局限性: 1. 自己写,不能自己读。

2. 数据不可以反复读。

3. 半双工通信。

4. 血缘关系进程间可用。

pipe 函数:

创建,并打开管道: int pipe(int fd[2]);

参数: fd[0]: 读端。

fd[1]: 写端。

返回值: 成功: 0

失败: -1 errno

管道的读写行为:

读管道:

1. 管道有数据,read 返回实际读到的字节数。

2. 管道无数据:1)无写端,read 返回 0 (类似读到文件尾)

2)有写端,read 阻塞等待。

写管道:

1. 无读端, 异常终止。 (SIGPIPE 导致的)

2. 有读端: 1) 管道已满, 阻塞等待

2) 管道未满, 返回写出的字节个数。

:使用管道实现父子进程间通信,完成:ls | wc -l 假定子进程(兄)实现 ls,子进程(弟)实现 wc

ls 命令正常会将结果集写到 stdout。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>

void sys_err(const char *str){
    perror(str);
    exit(1);
}
int main(int argc, char *argv[]){
    int fd[2];    // 建立管道数组
    int ret, i;
    pid_t pid;
    
    ret = pipe(fd);    // 建立管道
    if(ret == -1) sys_err("pipe error");    // 建立失败
    
    for(i = 0; i < 2; i++){
        pid = fork();    // 多进程
        if(pid < 0) sys_err("fork error");
        if(pid == 0) break;    // 子进程直接退出循环
    }
    
    if(i == 0){    // 兄进程
        close(fd[0]);    // 关闭读端
        dup2(fd[1], STDOUT_FILENO);    // 将标准输出写入管道
        execlp("ls", "ls", NULL);    // 执行ls命令,执行成功就会跳转到其他程序不继续执行当前程序
        sys_err("ls error");
    }
    else if(i == 1){    // 弟进程
        close(fd[1]);    // 关闭写端
        dup2(fd[0], STDIN_FILENO);    // 将读管道写入到标准输入中
        execlp("wc", "wc", "-l", NULL);    // 执行wc命令
        sys_err("ls error");
    }
    else if(i == 2){    // 父进程
        close(fd[0]);
        close(fd[1]);
        wait(NULL);    // 回收进程
        wait(NULL);
    }
    return 0;
}

fifo命名管道

管道的优劣:

优点:简单,相比信号,套接字实现进程通信,简单很多。

缺点:1.只能单向通信,双向通信需建立两个管道。

2.只能用于有血缘关系的进程间通信。该问题后来使用 fifo 命名管道解决。

fifo 管道:可以用于无血缘关系的进程间通信。

命名管道: mkfifo

无血缘关系进程间通信:

读端,open fifo O_ RDONLY

写端,open fifo O_ WRONLY

fifo 操作起来像文件:

建立fifo文件:mkfifo("fifo_name", 0644);

向管道写数据:fd = open("fifo_name", O_WRONLY); write(...);

向管道读数据:fd = open("fifo_name", O_RDONLY); read(...);

*当一个写端多个读端的时候,由于数据一旦被读走就没了,所以多个读端的并集才是写端的写

入数据。

*在阻塞模式下使用open打开FIFO文件的时候,read端会阻塞等待write端open打开文件,直到write进程也使用open打开FIFO的时候,read进程中的open才会返回,反过来也是一样。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值