在一个系统中,有若干进程,他们需要和os交互,以申请资源并得到os的管理,那么第一个问题便是如何交互?进程和具体的哪个部分交互?
答案是进程通过系统调用将控制权交给内核,之后内核完成一系列的动作,包括资源的分配和进程的管理等等。
那么系统调用和内核又是什么呢?进程与内核交互的模型又是什么呢?
内核就是一组全局变量和若干函数,它的功能一般是实现比较底层任务,和用户进程的函数没什么不同,但由于内核函数一般运行与核心态,而用户函数运行于用户态,
导致其权限不同而已。另外,他们所处的地址空间不同,下文会详细说明。系统调用指os给进程的接口,包含一组内核函数,能够完成特定的任务。
进程和内核交互的模型有三种:
1.独立运行的内核
这是早期的os模型,os代码(内核)作为一个实体独立与应用进程,os与进程不存在关联。当进程发生系统调用、中断等时,发生进程上下文切换,陷入内核。那么它的缺点也很明确,内核函数很难并行执行。
这里又有两个问题,什么是用户态和核心态?
他们都是指CPU的状态,在用户态下,运行的函数权限较小,用户进程一般运行在用户态;核心态下,cpu权限较大,内核函数运行在核心态。
还有一个问题值得注意,用户态下与内核态下用的栈是不同的,稍后会详细说明。
2.内核在进程内执行
动机:为了提高内核函数的并发性,在创建进程的时候会为其分配内核栈,用于内核函数的执行。这样进程在用户态和核心态切换时,不在需要进程上下文切换,节省开销。
3.微内核-os作为切换进程
此时,os的功能被抽象为一个个的服务器进程,只有少量的工作,比如进程切换和通信,中断等仍在微内核内完成,其余的任务都转交给运行与
用户态的服务器进程,内核的工作更多的是一个中介,沟通用户进程和服务器进程。其优点或动机在于其模块化明显,方便扩充与修改,适用于分布式布置等。缺点在于进程间通信必须通过内核,效率低。
那么,下一个问题是os代码与用户的进程代码存放在什么位置呢?包括用户态和核心态下的进程栈。
以上述内核在进程中运行为例,这个问题需要虚拟内存的知识。
总的来说,linux下,os给每个进程分配4G的内存空间(具体实现通过虚拟内存机制,不详细说明),其中0-3G的空间是用户进程的空间,每个进程都有自己的0-3G的进程空间,他们互相不会干扰(受益与虚拟内存机制),所有用户进程共享3G-4G的空间,内核和每个进程的核心栈以及其它系统信息便加载到这段地址空间中。只有在核心态下,才能访问这段空间。
那么,进程是如何访问0-4G内存的呢?这需要分段及分页+虚拟内存的知识。
os是如何标记与管理进程的呢?这需要cpu的寄存器和进程管理的知识。
进程间是如何相互通信与共享呢?共享中会出现临界区问题,是如何解决的呢?