进程之间需要协作完成一个事情,往往就需要通信,而且这个问题是面试的时候,面试官非常喜欢问的问题,很少有面试官会去问操作系统页面置换算法的。本文就介绍一下进程之间常用的通信方式。
信号是在软件层面对中断的模拟。
信号一般有三种处理方式,如下:
下面详细解释一下第三种,捕获的处理流程。
图片来源:清华大学操作系统公开课
上图的处理流程如下:
第一步:进程X把信号处理函数注册到操作系统内核
第二步:操作系统接受到一个信号,然后需要中断进程的执行切换到信号处理函数
第三步:修改应用程序的堆栈,让栈中要执行的下一条指令切换到信号处理函数,当信号处理函数结束的时候,重新从刚刚修改的地方开始执行
一般来说作为一个用户程序不会自己编写信号处理函数,往往是木马病毒会这样做。
只能发送系统定义好的信号,无法发送具体的自定义信息。
管道对于管道两端的进程而言就是文件,但是这个文件是一个特殊的文件,不属于文件系统。工作机制就是一个进程向管道写数据,另一个进程从管道读数据。管道是半双工的,数据只能向一个方向流动,如果想互相传输数据,需要搞两个管道。
传输数据只能是字节流,无法传输结构化数据。
消息队列按照FIFO的方式管理消息。
我们常见的更多是线程之间共享内存,因为同一个进程下面的线程可以共享进程堆,栈,文件系统,虚拟地址空间等,而不同进程之间共享内存就要求不同进程在虚拟地址空间映射的时候,映射到同一个物理空间,共享内存的效率很高属于直接通信,而上面介绍的那几个都是间接通信,但是控制机制很复杂,因为牵涉到进程并发时的安全问题,所以在多个进程同时写的时候要加锁处理,系统中没有实现这种同步机制,需要程序员自己控制。
看别的老铁的文章说共享内存之所以很快是只复制了两次,如下:
输入文件 ——> 共享内存 ——> 输出文件
管道和消息队列需要复制4次,所以性能比较低。理由是管道和消息队列都需要系统调用,拷贝过程如下:
输入文件 ——> 进程A ——> 内核缓冲区 ——> 进程B ——> 输出文件
我是没有搞明白上面从输入文件到进程A这个过程,如果这个需要,那共享内存也应该有这个过程,有明白的大佬,麻烦评论告知一下。
参考文章:
清华大学操作系统公开课(陈瑜老师)
原文:https://www.cnblogs.com/gunduzi/p/13534227.html