windows 和 linux 内核的区别
内核是操作系统中应用连接硬件设备的桥梁。
内核的能力
- 内核至少应该提供以下 4 种基本能力:
- 管理进程、线程(决定哪个进程、线程使用 CPU);
- 管理内存(决定内存用来做什么);
- 连接硬件设备(为进程、和设备间提供通信能力);
- 提供系统调用(接收进程发送来的系统调用)。
- 操作系统分层
进程和内核的关系, 是不是像浏览器请求服务端服务??
内核权限非常高,它可以管理进程、可以直接访问所有的内存,因此确实需要和进程之间有一定的隔 离。这个隔离用类似请求/响应的模型,非常符合常理。但是在浏览器、服务端模型中,浏览器和服务端是用不同的机器在执行,因此不需要共享一个 CPU。但是在进程调用内核的过程中,这里是存在资源共享的。
- 多数操作系统的设计都遵循一个原则:进程向内核发起一个请求,然后将 CPU 执行权限让出给内核。内核接手 CPU 执行权限,然后完成请求,再转让出 CPU 执行权限给调用进程。
linux的设计
- MultiTask 指多任务,Linux 是一个多任务的操作系统。多任务就是多个任务可以同时执行,当然 Linux 也支持并发
- SMP 指对称多处理:Linux 下每个处理器的地位是相等的,内存对多个处理器来说是共享的, 每个处理器都可以访问完整的内存和硬件资源。
- ELF 中把文件分成了一个个分段(Segment),每个段都有自己的作用.
Monolithic Kernel
宏内核: Linux 是宏内核架构,这说明 Linux 的内核是一个完整的可执行程序,且内核用最高权限来运行,特点就是有很多程序会打包在内核中Microkernel
微内核,内核只保留最基本的能力。比如进程调度、虚拟内存、中断。多数 应用,甚至包括驱动程序、文件系统,是在用户空间管理的。宏内核的特点就是有很 多程序会打包在内核中
分层其实差不多,区别在于比如说驱动程序是需要频繁调用底层能力的,如果在 内核中,性能肯定会好很多。对于微内核设计,驱动在内核外,驱动和硬件设备交互就需要频繁做内核 态的切换。
- windows NT 内核 NT:new technology
- 也支持Multitask 和 SMP(对称多处理) , 混合类型的内核,
- 有自己的可执行文件格式 PE 。
内核态与用户态
Kernel 运行在超级权限模式(Supervisor Mode)下,所以拥有很高的权限。按照权限管理的原则,多 数应用程序应该运行在最小权限下。
操作系统将内存分成了两个区域:
- 内核空间(Kernal Space),这个空间只有内核程序可以访问.
- 用户空间(User Space),这部分内存专门给应用程序使用。
- 内核态:在内核态空间运行的程序 用户态 : 在用户空间运行的程序。
系统调用过程
- 内核程序执行在内核态(
Kernal Mode
),用户程序执行在用户态(User Mode
)。当发 生系统调用时,用户态的程序发起系统调用。因为系统调用中牵扯特权指令,用户态程序权限不足,因 此会中断执行,也就是 Trap
(Trap 是一种中断)。
进程与线程
- 一个应用程序启动后会在内存中创建一个执行副本,这就是进程。
Linux
的内核是一个 Monolithic Kernel
(宏内核),因此可以看作一个进程。也就是开机的时候,磁盘的内核镜像被导入内存作为一个 执行副本,成为内核进程。 - 进程可以分成用户态进程和内核态进程两类。用户态进程通常是应用程序的副本,内核态进程就是内核 本身的进程。如果用户态进程需要申请资源,比如内存,可以通过系统调用向内核申请。
- 程序在现代操作系统中并不是以进程为单位在执行,而是以一种轻量级进程(Light Weighted Process),也称作线程(Thread)的形式执行。
- 一个进程可以拥有多个线程。进程创建的时候,一般会有一个主线程随着进程创建而创建。
那么用户态进程如果要执行程序,是否也要向内核申请呢?
其实不是,进程可以通过 API 创建用户态的线程,也可以通过系统调用创建内核态的线程。
用户态线程
- 用户态线程也称作用户级线程(User Level Thread),完全是在用户空间中创建
优点 - 管理开销小:创建、销毁不需要系统调用。
- 切换成本低:用户空间程序可以自己维护,不需要走操作系统调度。
缺点 - 与内核协作成本高:比如这种线程完全是用户空间程序在管理,当它进行 I/O 的时候,无法利用到 内核的优势,需要频繁进行用户态到内核态的切换。
- 线程间协作成本高:设想两个线程需要通信,通信需要 I/O,I/O 需要系统调用,因此用户态线程 需要支付额外的系统调用成本。
- 无法利用多核优势:比如操作系统调度的仍然是这个线程所属的进程,所以无论每次一个进程有多 少用户态的线程,都只能并发执行一个线程,因此一个进程的多个线程无法利用多核的优势。
- 操作系统无法针对线程调度进行优化:当一个进程的一个用户态线程阻塞(Block)了,操作系统 无法及时发现和处理阻塞问题,它不会更换执行其他线程,从而造成资源浪费。
内核态进程
- 内核态线程也称作内核级线程(Kernel Level Thread)。这种线程执行在内核态,可以通过系统调用创 造一个内核级线程。
优点 - 可以利用多核 CPU 优势:内核拥有较高权限,因此可以在多个 CPU 核心上执行内核线程。
- 操作系统级优化:内核中的线程操作 I/O 不需要进行系统调用;一个内核线程阻塞了,可以立即让 另一个执行。
缺点 - 创建成本高:创建的时候需要系统调用,也就是切换到内核态。
- 扩展性差:由一个内核程序管理,不可能数量太多。
- 切换成本较高:切换的时候,也同样存在需要内核操作,需要切换内核态。
用户态线程和内核态线程之间的映射关系
- 线程简单理解,就是要执行一段程序。程序不会自发的执行,需要操作系统进行调度。
如果有一个用户态的进程,它下面有多个线程。如果这个进程想要执行下面的某一个线程,应 该如何做呢?
将需要执行的程序,让一个内核线程去执行,内核线程是真正的线程。因为它会分配到 CPU 的执行资源。用户态线程创建成本低,问题明显,不可以利用多核。内核态线程,创建成本高,可以利用 多核,切换速度慢。因此通常我们会在内核中预先创建一些线程,并反复利用这些线程。
多对一(Many to One)
- 用户态进程中的多线程复用一个内核态线程。这样,极大地减少了创建内核态线程的成本,但是线程不 可以并发。
一对一(One to One)
- 该模型为每个用户态的线程分配一个单独的内核态线程,在这种情况下,每个用户态都需要通过系统调 用创建一个绑定的内核线程,并附加在上面执行.
- 因为线程较多,对内核调度的压力会明显增加。
多对多(Many To Many)
- n 个用户态线程分配 m 个内核态线程。m 通常可以小于 n,一种可行的策略是将 m 设 置为核数,减少了内核线程,同时也保证了多核心并发。
两层设计(Two Level)
中断的设计
- 第一层是硬件设计、第二层是操作系统设计、第三层是程序语言的设计。
- 按键码的收集,是键盘芯片和主板的能力。主板知道有新的按键后,通知 CPU,CPU 要中断当前执行的 程序,将 PC 指针跳转到一个固定的位置,我们称为一次中断(interrupt)。
- 中断类: 中断识别码。
- 中断向量(Interupt Vector) : PC指针跳转的地址,存储zai中断向量表中。
- PU 接收到中断后,CPU 根据中断类型操作 PC 指针,找到中断向量。操作系统必须在这之前,修 改中断向量,插入一条指令。比如操作系统在这里写一条Jump指令,将 PC 指针再次跳转到自己处理对 应中断类型的程序。
- 作系统接管之后,以按键程序为例,操作系统会进行一些处理,包括下面的几件事情:
- 1.将按键放入一个队列,保存下来。这是因为,操作系统不能保证及时处理所有的按键,比如当按键 过快时,需要先存储下来,再分时慢慢处理。
- 2.计算组合键。可以利用按下、释放之间的时间关系。
-
- 经过一定计算将按键抽象成消息(事件结构或对象)。
-
- 提供 API 给应用程序,让应用程序可以监听操作系统处理后的消息。
-
- 分发按键消息给监听按键的程序。
中断的类型
1、 触发方分成同步中断和异步中断;
2、是否强制触发分成可屏蔽中断和不可屏蔽中断。
- 中断可以由 CPU 指令直接触发,这种主动触发的中断,叫作同步中断。
- 系统调用,需要从用户态切换内核态,这种情况需要程序触发一个中断,叫作陷阱 (Trap),中断触发后需要继续执行系统调用。
- 错误(Fault),通常是因为检测到某种错误,需要触发一个中断,中断响 应结束后,会重新执行触发错误的地方,比如后面我们要学习的缺页中断。
- 最后还有一种情况是程序的异常,这种情况和 Trap 类似,用于实现程序抛出的异常
- 另一部分中断不是由 CPU 直接触发,是因为需要响应外部的通知,比如响应键盘、鼠标等设备而触发的 中断。这种中断我们称为异步中断。
- CPU 通常都支持设置一个中断屏蔽位(一个寄存器),设置为 1 之后 CPU 暂时就不再响应中断。对于 键盘鼠标输入,比如陷阱、错误、异常等情况,会被临时屏蔽。但是对于一些特别重要的中断,比如 CPU 故障导致的掉电中断,还是会正常触发。可以被屏蔽的中断我们称为可屏蔽中断,多数中断都是可 屏蔽中断。
思考题
Linux 内核和 Windows 内核有什么 区别?
- Windows 有两个内核,最新的是 NT 内核,目前主流的 Windows 产品都是 NT 内核。NT 内 核和 Linux 内核非常相似,没有太大的结构化差异。
- 从整体设计上来看,Linux 是宏内核,NT 内核属于混合型内核。和微内核不同,宏内核和混合类型内核 从实现上来看是一个完整的程序。只不过混合类型内核内部也抽象出了微内核的概念,从内核内部看混 合型内核的架构更像微内核。
- 其他差异 : Linux 内核是一个开源的内核;它们支持的可执行文件格式不同;它们用到的虚拟化技术不同
Unix 和 Macintosh 内核属于哪种类型?
- Unix : 宏内核。
- Mac OS 用的是 XNU 内核, XNU 是一种混合型内核,XNU 是 X is not Unix 的意思, 是一个受 Unix 影响很大的内核。
用户态线程和内核态线程的区别?
Java/Js 等语言为什么可以捕获到键盘 输入?
【解析】 为了捕获到键盘输入,硬件层面需要把按键抽象成中断,中断 CPU 执行。CPU 根据中断类型 找到对应的中断向量。操作系统预置了中断向量,因此发生中断后操作系统接管了程序。操作系统实现 了基本解析按键的算法,将按键抽象成键盘事件,并且提供了队列存储多个按键,还提供了监听按键的 API。因此应用程序,比如 Java/Node.js 虚拟机,就可以通过调用操作系统的 API 使用键盘事件
操作系统可以处理键盘按键可以理解,那么我们开机的时候 也可以使用键盘,但是那时候操作系统还没有载入内存,这个怎么解释?
- 主板的一块
ROM
上往往还有一个简化版的操作系统,叫 BIOS(Basic Input/Ouput System
)。在 OS
还没有接管计算机前,先由 BIOS
管理机器,并协助加载 OS
到内存。早期的 OS
还 会利用 BIOS
的能力,现代的 OS
接管后,就会替换掉 BIOS
的中断向量。