进程间通信 -- 各种通信方式的一方天地

举报
看,未来 发表于 2020/12/29 22:42:43 2020/12/29
【摘要】 真是个好问题 今天突然被 ==“不同场景下该如何选择进程间通信方式?”==给噎着了,这我还真没认真想过,以前只知道说它们都是什么?为什么?怎么用?还真没想过什么时候用谁?这个问题。 管道 在shell中管道用“|”表示。管道的历史很悠久了。 可以理解为内存中的一个缓冲区,用于将某个进程的数据流导入,由某一个进程导出,实现通信。 这种管道是没有名字,所以「|...

真是个好问题

今天突然被 ==“不同场景下该如何选择进程间通信方式?”==给噎着了,这我还真没认真想过,以前只知道说它们都是什么?为什么?怎么用?还真没想过什么时候用谁?这个问题。

在这里插入图片描述

管道

在shell中管道用“|”表示。管道的历史很悠久了。

可以理解为内存中的一个缓冲区,用于将某个进程的数据流导入,由某一个进程导出,实现通信。

这种管道是没有名字,所以「|」表示的管道称为匿名管道,用完了就销毁

注意,这个匿名管道是特殊的文件,只存在于内存,不存于文件系统中。

匿名管道用于有血缘关系的进程间通信。

在 shell 里面执行 A | B命令的时候,A 进程和 B 进程都是 shell 创建出来的子进程,A 和 B 之间不存在父子关系,它俩的父进程都是 shell。

在这里插入图片描述
如果要用管道进行无血缘关系之间的进程通信,用FIFO有名管道。

局势到这里已经很清楚了,管道具有:“召之即来,挥之即去,且不占文件系统位置”的特性,适合用于shell中的“一次性博弈”。

如果是“长期博弈”,它不行,得往后看。

消息队列

相对于管道的种种限制,消息队列就显得明智多了,因为它存着“尾款”啊,所以在系统中存留的必要性就大了。

1、消息队列是内核地址空间中的内部链表,通过Linux内核在不同的进程间传递消息。
2、消息顺序的发送到消息队列中,并以几种不同的方式从队列中获取。
3、内核中的消息队列是通过IPC标识符来进行区别的,不同消息队列之间是互相独立的。
4、每个消息队列中的消息又构成一个独立的链表。

我把它看作一个“丰巢”。

但是吧,消息队列固然有它的局限性在:
消息队列不适合比较大数据的传输,因为在内核中每个消息体都有一个最大长度的限制,同时所有队列所包含的全部消息体的总长度也是有上限。在 Linux 内核中,会有两个宏定义 MSGMAX 和 MSGMNB,它们以字节为单位,分别定义了一条消息的最大长度和一个队列的最大长度。

消息队列还是很赞的,单看上面这些特性,比管道占地方,比后面要讲的SHM慢,传输消息大小也不如MMP,还异步,靠。
就是这么个“一无是处”的通信方式,硬生生把自己的劣势转化为了优势,不然它都不知道被压到哪个箱底去了。

对,就是异步

随着“异步业务”的出现(如双十一流量削峰、秒杀系统等),消息队列突然就成了香饽饽,它能承载的消息比管道多,它也不追求速度,占用的内存还比MMP小,简直就是用来做流量削峰、解耦、异步的神器。

RobbieMQ、RocketMQ、Kafka。消息队列:解耦、异步、流量削峰。当下流行的几款MQ以及新手上路该如何选择MQ?

消息队列火了,命运也真是神奇啊。

内存共享映射(SHM)

1、共享内存是在多个进程之间共享内存区域的一种进程间的通信方式。
2、它是在多个进程间通过对指定内存段进行映射实现内存共享的。
3、这是IPC最快捷的方式,因为它没有中间商赚差价。
4、多个进程间共享的是同一块物理空间,仅仅是挂载地址不同而已,因此不需要进行复制,可以直接使用这段空间。
在这里插入图片描述

优点很明显了,快,承载数据量也够,一般用来进行进程间数据包通信(数据包不会太大,而且量多)。

但是如果要进行大文件操作,那这个就有点吃不消了,不是说不行,是扬短避长了哈哈哈,千里马非要它去拉磨。

文件内存映射(MMP)

1、mmap()函数用来将文件或者设备映射到内存中。
2、mmap的特点是按需调页。最开始只申请vma,并不调真正的页。当对某些页进行引用的时候,会引起一个缺页中断,再将页面调入到内存当中,这样避免了对内存的浪费。

mmap的优势: 操作文件就像操作内存一样,适合于对较大文件的读写。

mmap的缺点:
1、文件如果很小,比如60bytes,由于在内存当中的组织都是按页组织的,将文件调入到内存当中是一个页4k,这样其他的4096-60=4036 bytes的内存空间就会浪费掉了。

信号量

进程间通信的信号量其实我不是很想讲,现在高并发都是线程实现了,用进程去做高并发的话,emmm,浪费。
信号也不提了。。

网络流通信(Socket)

前面提到的管道、消息队列、共享内存都是在同一台主机上进行进程间通信,那要想跨网络与不同主机上的进程之间通信,就需要 Socket 通信了。

使用Socket通信也是分布式服务的一个大前提。

使用网络通信时需要在终端上开端口,占用网络资源等等,而且还要在网络上跑一圈再回来,所以,如果是同一台主机上就不用过多考虑这个了,它的天地在“分布式部署”上。

文章来源: lion-wu.blog.csdn.net,作者:看,未来,版权归原作者所有,如需转载,请联系作者。

原文链接:lion-wu.blog.csdn.net/article/details/107748046

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。