进程的通信方式

1,586 阅读3分钟

五种方式:管道、消息队列、共享内存、信号量、socket

首先,是通过 管道 来通信

这种管道是匿名的,也就是说如果没有关系你找不到它,所以它只能用在有亲缘关系的进程间。 同时,由于管道间的通信是单向的,要进行通信必须创建两个管道。
管道存在于内存中,所以它的缓存区是有限的。

为了克服只能用于亲缘关系的匿名管道的缺点,提出了 有名管道(FIFO)

有名管道以磁盘文件的方式存在,故可以实现本机任意两个进程的通信。(管道名存在文件系统中,内容还是存在内存中的)
但是,有名管道的通知机制类似于缓存,就像一个进程把数据放在缓存中等着另一个进程取出来一样,必须在另一个进程将数据拿走后第一个进程才能返回,效率比较低下。

为了解决管道效率低下的问题,又提出了 消息队列

使用消息队列,一个进程在将数据放进消息队列中就可以立即返回而无需等待另一个进程了。
同时,消息队列不同于管道,它是存在于内核中的,只有在内核重启(操作系统重启)或显示地删除时,消息队列才会被真正删除。
但,它也有缺点,当进程发送的数据太大,并且两个进程的通信特别频繁时,就不适合使用消息队列模型了,因为这时候数据的拷贝会耗费很多时间去读内存。

共享内存 就很好的解决拷贝时间过长的问题了

那么,什么是共享内存呢?
系统分配给进程的并不是实际物理内存,而是虚拟内存空间,所以只要两个进程拿出一部分虚拟内存空间,映 射到同一片物理内存中,就实现了共享内存了,此时进程就可直接读写这一块内存而不需要进行数据的拷贝了。
共享内存最大的问题就是多进程竞争内存的问题。

为了解决进程同步问题,使用 信号量

信号量的本质就是一个计数器,用来实现进程之间的互斥与同步。例如信号量的初始值是 1,
然后a进程来访问内存1的时候,我们就把信号量的值设为0,然后进程b也要来访问内存1的时候,看到信号量的值为 0 就知道已经有进程在访问内存1了,这个时候进程b就会访问不了内存1。所以说,信号量也是进程之间的一种通信方式。

上述通信方式都是在一台主机之间的通信,那远程通信如何解决呢?

socket就派上了用场,例如我们平时通过浏览器发起一个http请求,然后服务器给你返回对应的数据,这种就是采 用 Socket 的通信方式了。

参考:
记一次面试:进程之间究竟有哪些通信方式? ---- 告别死记硬背
进程间通信IPC