既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
内核是操作系统中应用连接硬件设备的桥梁。
内核的能力
- 内核至少应该提供以下 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)
- 混合了多对多和一对一的特点
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!