每日一篇-7.29-进程通信
为什么需要进程通信
每个进程都是独立的,拥有各自不同的用户地址空间,进程之间看不到其他进程的的变量。所以进程之间交换数据需要通过在内核开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,进程B再从内核缓冲区把数据读走,即进程间通信。
共享内存通信
共享内存是进程间通信最简单的方式之一,共享内存允许两个或更多进程访问同一块内存,通过内存映射,将不同进程的虚拟内存空间映射到相同的物理内存中。
优点:速度快,一个进程向共享的内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。
缺点:需要进程互斥访问操作,否则进程之间会互相篡改数据。
套接字通信
套接字Socket相当于一个接口,是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象,上联应用层(用户进程),下联传输层(TCP,UDP)。
下面是面向连接的TCP时序图(图为https://www.cnblogs.com/myitn...)
文章图片
信号量通信
管道通信
所谓的管道,就是在内核开辟一串缓存。从管道的一端写入数据缓存到内核中,另一端读取,也就是从内核中读取这段数据。另外,管道传输的数据是无格式的流且大小受限。
管道是基于“管道流”的通信方式。JDK提供了PipedWriter
、 PipedReader
、 PipedOutputStream
、 PipedInputStream
。其中,前面两个是基于字符的,后面两个是基于字节流的。
使用管道多半与I/O流相关。当我们一个线程需要先另一个线程发送一个信息(比如字符串)或者文件等等时,就需要使用管道通信了。
匿名管道通信
管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
匿名管道,即没有名字的管道,如下面的|:
$ ps auxf | grep mysql
如何通过匿名管道实现进程间通信:
1.父进程创建管道,并用两个文件描述符(fd)指向管道的两端用于记录数据的位置
2.通过fork,父进程得到子进程,?进程也有两个?件描述符指向同?管道
3.为了避免父子进程间同时写入或读出,管道只支持单向通信,父进程关闭fd[0],子进程关闭fd[1],即?进程关闭管道读端,?进程关闭管道写端。?进程可以往管道?写,?进程可以从管道?读,管道是?环形队列实现的,数据从写端流?从读端流出,这样就实现了进程间通信。
消息队列通信
【每日一篇-7.29-进程通信】消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
消息队列与共享内存对比图:
文章图片
1.共享内存模型会建立起一块供协作进程共享的内存区域,进程通过向此共享区域读出或写入数据来交换信息。
2.消息传递模型通过在协作进程间交换消息来实现通信。
消息队列API:send(message) 和 receive(message)。
推荐阅读
- #|LeetCode每日一题——1161. 最大层内元素和
- #|LeetCode每日一题——593. 有效的正方形
- #|Leetcode每日一题——三个无重叠子数组的最大和
- 投稿|每日优鲜“原地解散”,生鲜电商何去何从?
- 大数据那些事|Kafka从入门到高级(一篇完结)
- 0920|0920 每日三个小故事
- 12.04【每日一词】antidote
- MYSQL(基本篇)——一篇文章带你走进MYSQL的奇妙世界
- 投稿|每日优鲜大败局:生鲜电商还是一门好生意吗?
- 投稿|每日优鲜跌倒,“友商”吃饱?