文章目录
了解用户态和核心态之前必须知道操作系统是干啥的
什么是OS?
操作系统是整个计算机系统的控制者
操作系统能访问整个内存地址空间
,能够决定CPU分配给哪个进程,可以控制各种设备,比如磁盘,网卡,键盘,鼠标
进程 os 系统调用三者之间的关系
举例理解:
-
囚犯就好比
进程
-
监狱就好比进程的
虚拟内存空间
-
警察就好比
操作系统
-
牢房上的小窗口就好比
系统调用
进程
可以通过系统调用
向操作系统
发起请求(囚犯通过小窗口向警察表达诉求),希望操作系统替自己去完成某项操作,但是操作系统怎么完成取决于OS自己而不受进程控制
用户态和核心态
为什么划分用户态和核心态?
因为操作系统需要限制进程的访问能力,所以分出用户态和核心态,使得进程在不同的状态下的访问能力不同。
为什么要限制进程的访问能力?
因为操作系统是整个计算机系统的控制者
如果某个进程能控制操作系统的话,那么这个进程就可以控制整个计算机系统,这是很可怕的。因此操作系统必须限制进程的访问权限。
核心态和用户态的区别
用户态
下用户进程操作计算机,执行权限小,例如禁止使用特权指令,不能直接取用系统资源,不能改变机器状态等。
核心态
由OS操控计算机,执行权限大很多,可以使用特权指令,能直接取用系统资源等,
用户态如何切换至内核态
我们知道操作系统其实也是一个程序
,本质上和用户程序
没有任何区别。
操作系统和用户程序都需要被编译成机器指令
才能被CPU执行。因此
- 当CPU执行的是来自
操作系统的机器指令
时,计算机表现出来的就是操作系统正在运行
(比如操作系统收发网络数据)。 - 当CPU执行的是来自
用户程序的机器指令
时,计算机表现出来的就是用户程序正在运行
(比如浏览器正在加载页面)。
从这里我们可以看出,单纯的依靠软件是没有办法来区分操作系统和用户程序的,因为这二者本质上都是机器指令
,因此要想限制进程必须还要依靠硬件CPU的帮助。
即:操作系统是利用CPU区分工作模式的功能来限制进程的
CPU是如何实现区分的?——借助四种特权集
指令集架构ISA是CPU和软件之间的桥梁。ISA包含指令集、特权集、寄存器等诸多方面
其中的特权级又被称为异常级别(Exception Level EL),共有四种特权级
注意,中断是用户态切换到内核态的唯一方式,另外两种底层都是利用的中断。
系统调用
系统调用是OS提供给用户直接调用的一组API,用户可以通过调用这些API向OS传达命令,同时由用户态转为内核态。
系统调用带来的好处
-
提高系统稳定性
作为用户程序和操作系统之间的一个屏障
,系统调用保护了操作系统不受用户程序的干扰。通过系统调用,操作系统可以对用户请求进行权限以及合法性检查,这就阻止了用户程序随意使用系统资源
。
同时作为用户程序向操作系统发起请求的唯一合法途径
,系统调用起到了类似海关的作用,这些无疑提高了系统稳定性。 -
释放了程序员生产力
系统调用对程序员屏蔽了操作系统对计算机资源管理的细节,因此程序员在进行比如文件读写这样的操作时根本无需关心这些文件放在了磁盘中的什么位置上,这些文件是通过什么样的文件系统来管理的等等事情。
系统调用的分类
-
进程控制:fork和wait
一个运行中的进程可以创建另外一个进程去完成某项工作,这样当前进程就有机会去处理自己感兴趣的事情,这类系统调用在Linux中是fork()
,当我们创建新的进程后,可能需要等待其运行完成,这时我们需要的系统调用是Linux下的wait()
。 -
文件管理:create open read write
我们通常需要创建文件create()
来持久化的保存信息,文件创建完毕后,通常在使用前我们要首先打开文件open()
,然后才能进行读写read()、write()
。文件使用完毕后,通常需要关闭文件close()
。关于文件的这些操作都是通过系统调用来完成的。 -
设备管理:request release
我们的程序在运行过程中需要使用很多系统资源才能完成任务,比如请求分配内存、访问磁盘、通过网卡收发网络数据等等,如果这些资源当前是可用的,那么我们的程序在得到这些资源后可以继续运行,否则只能暂停运行我们的程序直到这些资源可用为止。因此用户程序通常需要首先请求资源request
(),使用完毕后释放资源release
()。由于在Unix/Linux系统中将这些硬件资源抽象成了文件(file)
,因此我们可以通过对文件的读写read()、write()
就能实现操作设备的目的。 -
信息维护:date time dump trace
通常情况下我们需要向操作系统请求一些只有操作系统才知道的信息
,比如当前的日期date
(),时间time
(),或者操作系统的版本信息,当前可用内存大小,剩余磁盘大小等等。
另一种比较有用的信息是程序在内存中的运行数据
,通过dump
()进程在内存中的数据以及进程中函数的调用信息trace
(),我们就可以利用调试器(比如Linux下的gdb)来调试有问题的程序。 -
通信:
我们的进程可能需要与其它进程通信才能完成某项功能,在这里通常有两种通信模型。- 一种是
消息传递类
,比如常用的网络通信,在网络通信中我们通过读写socket来实现网络数据的接收recv
()和发送send
(),本地的进程之间通信会通过比如Linux下的pipe
()这类系统调用来完成。 - 另一种是
共享内存
。即进程间通信模型。
- 一种是
中断
在计算机中,中断是系统用来响应硬件设备请求
的一种机制,操作系统收到硬件的中断请求,会打断正在执行的进程,然后调用内核中的中断处理程序来响应请求,处理完中断请求之后再回去接着执行原先的进程。
中断的特点
-
最重要的一点:有了中断才能实现多程序并发执行
-
中断是cup从用户态进入核心态的
唯一途径
-
操作系统收到了中断请求,会打断其他进程的运行,所以中断请求的响应程序,也就是中断处理程序,要尽可能快的执行完,这样可以减少对正常进程运行调度地影响。
中断处理过程
主要有三项工作:
①保护现场和传递参数;
②执行相应的中断
③恢复和退出中断
软中断
我们知道,中断请求的处理程序要快
,这样才能减少对正常进程运行调度地影响,而且中断处理程序可能会暂时关闭中断
,这时如果中断处理程序执行时间过长,可能在还未执行完中断处理程序前,会丢失
当前其他设备的中断请求。
那 Linux 系统为了解决中断处理程序执行过长和中断丢失
的问题,将中断过程分成了两个阶段,分别是「上半部和下半部分」
。
- 上半部用来
快速处理中断
,一般会暂时关闭中断请求,主要负责处理跟硬件紧密相关或者时间敏感的事情。特点是快速执行——硬中断 - 下半部用来
延迟处理上半部未完成的工作
,一般以「内核线程
」的方式运行。特点是延迟执行
——软中断