进程间通信小结
下面简单的总结一下,自己对进程间通信的理解。首先,要意识到一点:各进程间拥有相互独立的地址空间,所以进程间无法在用户态完成通信,必须要借助操作系统,也就是内核态来完成相应的操作。
1.内核态和用户态
由上图可知,系统分为内核态和用户态,其中内核态包括内核,用户态主要指应用程序。内核控制了计算机的软件和硬件资源,为了便于应用程序也能使用由硬件提供的相关功能,操作系统提供了系统调用、shell(基于系统调用)和公用函数库(基于系统调用)。
1.进程间地址相互独立
各进程拥有相互独立的地址空间,彼此相互隔离,符合进程“操作系统资源分配最小单位”的地位。进程间相互独立的地址空间依赖MMU实现。Linux在操作内存的时候,首先由MMU查询页表,如果该地址上映射了实际的物理内存,就会换算成实际的物理地址;而由内核管理的这种虚实映射,是不可能将其它进程使用的物理内存,映射到本进程的虚拟地址上的,这样就实现了内存空间的隔离。
1.进程间通信
1)信号
一个进程可以通过kill函数向其他进程发送信号,其他进程可以在之前通过sigaction函数为对应的信号注册相关的函数操作。
2)信号量
我觉得信号量其实就是一个锁,负责对临界资源提供保护,一般和共享内存配合使用。主要是两个操作P和V,其中P操作负责申请临界资源,申请成功就将临界资源总数减一;V操作负责释放临界资源,释放成功就将临界资源总数加一。
3)共享内存
共享内存是在内核态实现的,依靠系统调用,多个进程可以将同一块虚拟内存映射到本进程对应的虚拟地址空间中。共享内存
4)Socket
Socket一般用于不同的计算机上不同进程之间进行通信,但也支持本机内的进程间通信。服务端:socket、bind、listen、accept;客户端:socket、connect。
5)消息队列
借助内核提供的消息队列结构,进程之间可以进行通信。异步通信。
6)命名管道
命名管道和消息队列类似也能用于不相关的两进程间进行通信。
补充:
- 消息队列是异步通信吗?
答:消息队列属于异步通信,用途很多,主要有解耦、异步和削峰。
解耦:类似于简单工厂模式,解耦了订单系统和其他系统之间耦合性过高的问题。如下图。
异步:顾名思义,通过异步可以提高并行性,减少系统的处理时间。
削峰:通过消息队列为系统提供了一层保护,防止业务量过大,跑死系统。
1.共享内存为何是效率最高的进程间通信方式?
答:可以这样理解,假如进程1需要将文件1中的内容发送给进程2,进程2再将收到的内容写到文件2中。
使用管道、消息队列:
A) 使用read函数,将文件1中的数据复制到进程1的临时缓冲区中。
B) 将进程1临时缓冲区中的数据复制到管道或消息队列中。
C) 进程2从管道或消息队列中将数据复制到自己的缓冲区中。
D) 进程2将缓冲区中的数据写入到文件2中。
使用共享内存:
A) 进程1从文件1中将数据读入到共享内存中。
B) 进程2将共享内存中的数据写入到文件2中。