计算机由各种外部硬件设备组成,如内存,cpu,硬盘等。如果每个程序要访问某个硬件,那它必须知道如何和这个硬件设备对接通信协议,那这样太麻烦了,因此这项工作交给了中间人-内核来负责,应用程序只需关心与内核交互,无需关心硬件细节
早期OS中,程序员设计代码直接访问硬件,以改进应用程序总体性能,这种方式可以使硬件快速响应,但是存在严重缺陷:
内核具有很大的权限,可以控制 cpu、内存、硬盘等硬件,应用程序具有的权限很小,因此大多数操作系统,把内存分成了两个区域:
用户空间的代码只能访问一个局部的内存看空间,而内核空间代码可以访问所有内存空间。因此,当程序使用用户空间时,我们常说该程序在用户态执行,而当程序使用内核空间时,程序则在内核态执行
应用程序如果需要进入内核空间,就需要通过系统调用,如下图
内核程序执行在内核态,用户程序执行在用户态。当应用程序使用系统调用时,会发生一个中断。发生中断后、cpu会中断当前正在执行的用户程序,转而跳转到中断处理程序,也就是开始执行内核程序。内核处理完毕后、主动触发中断,把cpu执行权限交还给用户程序,回到用户态继续工作
每个进程的用户地址空间都是不同的,一般而言不能互相访问,但是内核空间是每个进程共享的,所以进程之间通信必须通过内核
有匿名管道和命名管道两种
匿名管道:无名字标识,是特殊文件只存在于内存中,不存在于文件系统中,shell命令中的【|】竖线就是匿名管道,通信数据是无格式的字节流且大小受限,通信方式是单向的,只能用于存在父子关系的进程间通信,匿名管道声明周期随着进程创建而建立,随着进程终止而消亡
命名管道:可以在非亲缘关系进程间通信,因此使用命名管道前提就是在文件系统中创建类型为p的设备文件,那么毫无关系的进程就可以通过该设备文件进行通信,其他和匿名管道相同
匿名管道和命名管道,进程写入的数据都是缓存在内核中,另一个进程读取数据自然也是从内核中读取,同时通信数据遵循FIFO原则,不支持文件定位操作
本文由博客一文多发平台 OpenWrite 发布!