进程间通信2. 通信方式及各自特点

    经常使用到的进程间通信有:管道、消息队列和共享内存。
   
    管道
    最开始出现的管道是用于具有血缘关系的进程之间共享数据的。父进程首先创建一个管道,然后再fork()出子进程,子进程自动共享对管道的访问权限。这种管道是没有名字的(只有进程中的一个标识符进行标识),因此也称为匿名管道。
    如我们在shell中运行 ls * | grep foo 时,shell就会创建一个匿名管道,并把ls的stdout重定向到该管道的输入端,把grep的stdin重定向到管道的输出端,ls 的输出就自动的称为grep的输入。这一切对 ls 和 grep 都是透明的,它们并不知道管道的存在。
    后来就出现了FIFO(first in first out),也称为有名管道。 有名和无名是针对OS来说的,OS能直接管理到就是有名的,否则就是无名的。FIFO出现后,管道就不仅仅用于具有血缘关系进程的通信了,而是可以用于任意进程之间的通信。
    管道的生命周期是跟随进程的。当所有使用管道的进程退出或者所有进程都显示的调用close()后,管道就会被丢弃掉(其实进程退出等效于调用close(),因为进程退出时所有打开的资源标识符都会被OS关掉)。如果这时候管道中仍然有未读取的数据,这些数据同样被丢弃掉。而且在往管道中写入数据时,必须存在读取数据的进程,不然就没有任何意义了。

    消息队列
    消息队列的作用与管道类似,有足够写权限的进程可往消息队列中放置消息,有足够读权限的的进程可以从消息队列中读取消息。与管道不同的是在某个进程写入消息之前,并不需要另外某个进程在该队列上等待消息的到达。这是因为消息队列的声明周期是跟随内核的。只要内核不删除消息队列,即使进程退出了,消息队列依然是存在的。(不过在现有的OS的实现中,消息队列是通过引用计数的方式记录当前有多少个进程已经打开了自己,所有进程退出时,引用计数为0时,此时OS也会自动的删除消息队列)。

    共享内存
    共享内存也有两种:匿名共享内存和有名共享内存。它们的区别和上面提到的管道和FIFO一样,匿名共享内存只能用于具有血缘关系的进程间通信,有名共享内存则没有此限制。
    共享内存的声明周期也是跟随内核的。与上述两种方式最大的不同在于,使用共享内存沟通的进程之间进行数据交换是不经过系统调用进行进程--内核的数据copy过程的,所有的数据交换都是在内存中完成的。相比于前两种方式,共享内存的方式是速度最快的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值