进程间通信之管道

进程间通信

Linux环境下,进程地址空间相互独立,每个进程拥有各自的用户地址空间。一个进程的全局变量在其它进程中都是看不到的,所以进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内存缓冲区,进程2再从内核缓冲区把数据读走。内核提供的这种机制称为进程间通信(IPC, InterProcess Communication)。
在进程间完成数据传递需要借助操作系统提供特殊的方法,如:管道,命名管道,信号,消息队列,共享内存,信号量,套接字等。常用的进程间通信方式有:
1. 管道(使用最简单)
2. 信号(开销最小)
3. 共享内存区(无血缘关系)
4. 本地套接字(最稳定)

管道/匿名管道(PIPE)

管道的实质
管道的实质是内核利用**环形队列的数据结构在内核缓冲区的一个实现,默认设置大小为4K,可以通过 ulimit -a命令查看。由于利用环形队列进行实现,读和写的位置都是自动增长的,不能随意改变,一个数据只能被读取一次,读取后数据就会从缓冲区中移除。当缓冲区读空或者写满时,有一定的规则控制相应的读进程或者写进程进入等待队列,当空的缓冲区有新数据写入或者满的缓冲区有数据读出来时,就唤醒等待队列中的进程继续读写。管道的通信方式为:写端每次都将数据写入管道缓冲区的 末尾 ,而读端每次都从管道缓冲区的 头部 读出数据。管道对于两端通信的进程来说就只是一种文件,一种不属于文件系统仅存在内存中的“伪文件”管道的局限性

  • 管道是半双工,数据只能向一个方向流动,所以只支持单向数据流。
  • 只能用于具有亲缘关系(父子进程或者兄弟进程)的进程
  • 管道的缓冲区大小有限
  • 没有名称

管道的使用介绍

  1. 创建管道
int pipe(int pipefd[2]);//成功:0;失败:-1,设置errno

函数调用成功返回r/w两个文件描述符。无需open,但需要手动close。规定fd[0]->r; fd[1]->w。

  1. 父进程调用pipe函数创建管道,得到两个文件描述符fd[0],fd[1]指向管道的读端和写端。
  2. 父进程调用fork函数创建子进程,那么子进程也有两个文件描述符指向同一管道。
  3. 父进程关闭管道读端,子进程关闭管道写端。父进程可以向管道中写入数据,子进程将管道中的数据读出。

总结如下:

  • 读管道
    管道中有数据,read返回实际读到的字节数
    管道中无数据:
    管道写端被全部关闭,read返回0(就像读到文件结尾)
    管道写端没有全部被关闭,read阻塞等待(可能将有数据抵达,此时会让出CPU)

  • 写管道
    管道读端全部被关闭,进程异常终止(也可使用SIGPIPE信号,使进程不终止)
    管道读端没有全部关闭
    管道已满,write阻塞
    管道未满,write将数据写入,并返回实际写入的字节数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值