进程间通信之——管道

进程间通信(inter process communite)之管道

1.管道的分类

  1. 有名管道、没有血缘关系的进程间通讯fifo()
  2. 无名管道、只能进行父子进程间的通讯pipe()
  3. 不管是有名管道还是无名管道都是往内核中写数据

2.管道的实现:环形队列

3.管道的大小:4K

4.局限性:数据只能读取一次,不能重复读取,头指针write在前面写,尾指read在后面读,循环读

5.模式:半双工(单项数据流动)

6.创建无名管道

原型:int pipe(int fd[2]);fd是传出参数 fd[0]读端 fd[1]写端
读操作

        有数据:read正常读,返回出字节数
         无数据
                   写端全部关闭
                            1.read接触阻塞,返回0,相当于读文件读到了尾部
                            2.写端没有全部关闭  read阻塞
写操作
         读端全部关闭:管道破裂,进程被终止,内核给当前进程发送SIGPIPE信号
         读端没有全部关闭:缓冲区写满了,write阻塞,反之,没有被写满,write继续写

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include<unistd.h>
  5 
  6 int main()
  7 {
  8     int fd[2];
  9     int ret = pipe(fd);     //创建一个无名管道
 10     if(ret == -1)
 11     {
 12         perror("pipe failed!");
 13         exit(1);
 14     }
 15 
 16     pid_t pid = fork();
 17     if(pid == -1)
 18     {
 19         perror("fork error!");
 20         exit(1);
 21     }
 22 
 23     if(pid > 0)  //父进程负责往管道中写入数据
 24     {
 25         close(fd[0]);    //关闭读段
 26         dup2(fd[1],1);   //用标准输出覆盖管道的写端,把数据写道管道中去
 27         execlp("ps","ps","aux",NULL);   //这个是父进程执行的命令和参数 ps -aux
 28 
 29         perror("execlp error!");
 30         exit(1);
 31     }
 32      //子进程负责读数据并且打印在终端上
 33     if(pid == 0)
 34     {
 35         close(fd[1]);   //关闭写段
 36         dup2(fd[0],0);  //用标准输入覆盖管道的读端,把数据从管道中读出来
 37         execlp("grep","grep","bash",NULL);  //执行的命令是 grep | bash
 38         perror("grep error!");
 39         exit(1);
 40     }
 41 
 42 
 43     close(fd[0]);
 44     close(fd[1]);
 45     return 0;
 46 }

7.有名管道

有名管道原理 :在磁盘上创建一个fifo文件,不管在这个文件内写多少,文件大小都为0,因为在内核中这个fifo文件会有一个对应的缓冲区,写入的数据会导入到这个缓冲区中,所有这个文件大小一直会为0.

两个不相关的进程通信

创建fifo文件命令:mkfifo main

接下来的操作和操作文件,一遍读文件,一遍写文件,这样进程间通信就成功了。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值