linux 管道、消息队列、共享内存的对比

------管道

管道的优点是不需要加锁,缺点是默认缓冲区太小,只有4K,同时只适合父子进程间通信,而且一个管道只适合单向通信,如果要双向通信需要建立两个。而且不适合多个子进程,因为消息会乱,它的发送接收机制是用read/write这种适用流的,缺点是数据本身没有边界,需要应用程序自己解释,而一般消息大多是一个固定长的消息头,和一个变长的消息体,一个子进程从管道read到消息头后,消息体可能被别的子进程接收到

------消息队列

消息队列也不要加锁,默认缓冲区和单消息上限都要大一些,在我的suse10上是64K,它并不局限于父子进程间通信,只要一个相同的key,就可以让不同的进程定位到同一个消息队列上,它也可以用来给双向通信,不过稍微加个标识,可以通过消息中的type进行区分,比如一个任务分派进程,创建了若干个执行子进程,不管是父进程发送分派任务的消息,还是子进程发送任务执行的消息,都将type设置为目标进程的pid,因为msgrcv可以指定只接收消息类型为type的消息,这样就实现了子进程只接收自己的任务,父进程只接收任务结果

------共享内存

共享内存的几乎可以认为没有上限,它也是不局限与父子进程,采用跟消息队列类似的定位方式,因为内存是共享的,不存在任何单向的限制,最大的问题就是需要应用程序自己做互斥,有如下几种方案

1 只适用两个进程共享,在内存中放一个标志位,一定要声明为volatile,大家基于标志位来互斥,例如为0时第一个可以写,第二个就等待,为1时第一个等待,第二个可以写/读

2 也只适用两个进程,是用信号,大家等待不同的信号,第一个写完了发送信号2,等待信号1,第二个等待信号2,收到后读取/写入完,发送信号1,它不是用更多进程是因为虽然父进程可以向不同子进程分别发送信号,但是子进程收到信号会同时访问共享内存,产生不同子进程间的竞态条件,如果用多块共享内存,又存在子进程发送结果通知信号时,父进程收到信号后,不知道是谁发送,也意味着不知道该访问哪块共享内存,即使子进程发送不同的结果通知信号,因为等待信号的一定是阻塞的,如果某个子进程意外终止,父进程将永远阻塞下去,而不能超时处理

3 采用信号量或者msgctl自己的加锁、解锁功能,不过后者只适用于linux

------总结

管道是最弱的,只适合有限场景;

消息队列能适合大部分场景,缺点是默认缓冲也比较小,不过这个可以调整,前提是你有管理员权限;

具体见http://blog.csdn.net/xiaofei0859/article/details/5868478

共享内存是最强大的,只是要做互斥

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值