这部分从对内核空间和用户空间的设计理解、切换场景及具体的C库函数进行介绍。
分离用户空间与内核空间的设计理解:
- 计算机资源和操作系统的保护:比如内核中包含对进程的描述、对设备、文件的控制,与这些相关的操作必须通过系统调用执行;
- 开发角度的设计(底层抽象):运行在用户态的程序被限制在具体的用户空间中执行用户需要的程序,分离操作系统提供的功能程序,同时也是对资源的保护。
操作系统发生状态切换,空间切换的场景:
说到空间切换或者状态切换,依目前理解都与进程相关,所以一下用进程的生命周期介绍发生场景。
进程创建时:
需要内核空间初始化进程PCB,分配空间并设置页表,需要切换。
进程运行中执行或被执行操作:
-
IPC类型操作:如创建Semaphore、socket或管道通信等,都需要操作系统进行记录,
API:以socket建立为例,bind,listen等 -
对设备(文件)读写:对硬盘文件的读写,对tty伪设备读写等
API:read,write,fopen,fclose,printf等 -
生成子进程:fork(),exec()等操作
注册的信号通知:内核得到信号,通知进程,此时应该算是内核空间向用户空间的主动切换。
被中断、调度:进程的时间片运行结束,此时内核将进程挂起,PCB上保存现场信息等,状态到了内核态。
API:与调度相关的比如<sched.h>库中设置进程nice值的函数 -
进程被唤醒的时候:从挂起或就绪到运行,设置完PCB信息,进程重新运行,状态到了用户态,。
进程退出的时候:主动exit(),需要内核清除PCB的信息、释放指向的内存空间,检查子进程,调整子进程归属等,属于陷入内核态的过程。