IPC的选择

常见的进程间通信方式大概有如下几种:管道、消息队列、共享内存、套接字。以前只是大概了解了这几种实现方式,但对于如何选择一种合适的通信方式一直没有清晰的认识,这几天抽空查阅了资料,顺便整理下。

管道

管道分命名管道与匿名管道,用作两个进程间通信,数据只能以字节流的方式单向传输,如果要双向通信,就得开两个管道。

有关管道的详细介绍可以参考:https://blog.csdn.net/qq_33724710/article/details/52345509

管道的可读性并不高(比如匿名管道一端关闭读,一端关闭写的操作),伸缩性也不够好(无法跨主机通信)。通常用在两个进程间发送一些频率很高、且数据非常短小的数据。整体来说管道通信使用频率不高,除非有特定需求。

消息队列

通过msgget/msgsnd/msgrcv系列函数创建一个消息队列,将新消息添加到队列尾端,从队列中读取消息。读消息不一定是按次序的,而是可以按消息类型读取消息。

有关消息队列的详细介绍可以参考:https://blog.csdn.net/qq_33724710/article/details/52354217

消息队列产生的最初目的主要是用于提供高于一般速度的IPC,但现在与其他形式的IPC相比,消息队列在速度上并没有明显的优势,没有理由支撑我们选它,所以现在的进程通信可以不考虑它了。

共享内存

两个进程通过虚拟内存空间映射至同一物理内存进行数据交换。详细介绍可以参考这篇文章:https://blog.csdn.net/qq_33724710/article/details/52413881

相比其它通信机制,共享内存传递数据没有经过内核中转,因此速度达到了极致。但由于多个进程可同时访问这块共享地址,需要有相应的同步、互斥机制配合使用,使用起来稍显麻烦,但大家都馋它速度快。共享内存之精髓在于共享二字,一般适用于多个进程之间共享一块size超大的数据,或者在一些需要追求极致效率、实时性要求高的情况下会用到,比如外汇系统(一秒钟几百万上下那种)。一般没有这样的硬性需求,也没必要去特意使用。

套接字

linux下套接字分为普通套接字、unix域套接字。前者通过ip:port标识一个地址,用作不同主机之间的通信,数据会转发经过协议栈一层层的封装;后者通过一个路径(如/tmp/cfgaddr)来标识一个地址,用作同主机不同进程间的通信,数据转发不经过协议栈封包,只在同主机上拷贝数据,效率比普通套接字要高,数据转发效率也不比除共享内存外的IPC差(即使同主机间用普通socket通信,对于当代计算机来讲,也不用特别计较这一点速度损失)。

socket大家都很熟了,但unix域套接字估摸着有些人就不是很清楚了,具体可以参考@alantu2018 这位同学的文章:https://www.cnblogs.com/alantu2018/p/8460269.html

现在的各种系统中,因性能不足而扩展为分布式的场景是很常见的(本来就是多进程了,迁移到多个主机上来提升性能也是挺自然的一件事),同个主机上的进程迁移到不同的服务器上,这时候通信的方式也要做改变,如果你的旧系统是socket通信的,那么简单的换个ip:port就完成了迁移。另外,还有个小差异:socket在进程退出后,文件描述符会被系统自动清理(unix域套接字还要细分),不像其它的IPC机制(命名管道、消息队列、共享内存),总有些玩意必须主动释放。

总体来说,socket其可读性可扩展性易操作性值得优先考虑。

最后

那么再总结一下,就是:

  • 跨主机通信,没得选只能用socket
  • 除非有特别明确的理由,否则优先考虑使用socket
  • 同主机通信,优先用unix域套接字
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fireplusplus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值