目录
进程间通信IPC (InterProcess Communication)
概念, 进程间通讯究竟是什么
每个进程都有各自不同的用户地址, 任何一个进程的全局变量在另一个进程中看不到, 所以进程与进程之间的通信(交换数据)就必须要通过内核, 在内核中开辟一块缓冲区.
进程A把数据从用户空间拷贝到缓冲区, 进程B再从内核缓冲区数据拿走.
内核提供这样的机制我们就叫他进程间通讯.
进程间通信的方式有几种, 它们又有什么样的特点?
管道/匿名管道(pipe)
-
只能用于父子进程或者兄弟进程之间的通信
-
管道是半双工的, 数据只能向一个方向流动, 所以当双方都需要通信时, 需要建立起两个管道
-
管道相对于管道两端的进程而言就是一个文件, 这个文件单独构成一种文件系统, 只存在于内存之中.
-
数据只能从管道缓冲区的头部读取, 从管道缓冲区的尾部写入, 就像队列一样
管道其实就是一个内核缓冲区, 我们可以拿这幅图和概念中的图进行对比
管道有比较大的局限性, 首先它没有名字, 又只支持具有亲缘关系的进程之间的单向数据流, 而且管道缓冲区有限. 管道传输的又是无格式的字节流, 所以管道的读出方和写入方必须事先约定好多少个字节算作一个消息.
有名管道(F I F O)
看到FIFO是不是就想到了First In First Out
事实上确实如此! 和匿名管道最大的不同就是它是有名字的, 所以它支持没有亲缘关系的进程之间的通信.
信号(Signal)
(突然想起了泽野弘之的那首曲子, 但是想不起来是那首了((有一句台词翻译成中文是你看见了那个信号吗
信号是Linux系统中用于进程间互相通信或者操作的一种机制, 信号可以任意时间发给某一进程
接下来有两种情况
if (进程未处于执行状态) {
while (进程没有回复执行并传递给他) {
信号被内核保护起来;
}
}
if (信号被进程设置为阻塞) {
while (阻塞没被取消) {
信号的传递被延迟
}
}
总结: 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生;
消息队列(Message Queuing)
消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。管道和消息队列的通信数据都是先进先出的原则。与管道(无名管道:只存在于内存中的文件;命名管道:存在于实际的磁盘介质或者文件系统)不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除一个消息队列时,该消息队列才会被真正的删除。消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比 FIFO 更有优势。消息队列克服了信号承载信息量少,管道只能承载无格式字 节流以及缓冲区大小受限等缺。
共享内存(Share Memory)
使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。
可以说这是最有用的进程间通信方式。
信号量(Semaphore)
信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信方式主要用于解决与同步相关的问题并避免竞争条件。
套接字(Socket)
此方法主要用于在客户端和服务器之间通过网络进行通信。套接字是支持 TCP/IP 的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。