共计 1207 个字符,预计需要花费 4 分钟才能阅读完成。
为什么须要过程通信
每个过程都是独立的,领有各自不同的用户地址空间,过程之间看不到其余过程的的变量。所以过程之间替换数据须要通过在内核开拓一块缓冲区,过程 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],即⽗过程敞开管道读端, ⼦过程敞开管道写端。⽗过程能够往管道⾥写, ⼦过程能够从管道⾥读, 管道是⽤环形队列实现的, 数据从写端流⼊从读端流出, 这样就实现了过程间通信。
音讯队列通信
音讯队列 (message queue):音讯队列是由音讯的链表,寄存在内核中并由音讯队列标识符标识。音讯队列克服了信号传递信息少、管道只能承载无格局字节流以及缓冲区大小受限等毛病。
音讯队列与共享内存比照图:
1. 共享内存模型会建设起一块供合作过程共享的内存区域,过程通过向此共享区域读出或写入数据来替换信息。
2. 消息传递模型通过在合作过程间替换音讯来实现通信。
音讯队列 API:send(message) 和 receive(message)。