【趣谈Linux操作系统】 学习笔记

本文带你探索Linux操作系统的比喻,从接待员到交付人员,理解系统调用与进程管理。深入剖析系统初始化、调度机制,涉及fork、内存管理、信号处理与通信,以及Glibc的作用。适合初学者快速掌握Linux核心原理。
摘要由CSDN通过智能技术生成

趣谈Linux操作系统

原文链接:https://blog.csdn.net/shijinghan1126/article/details/111162704

一、操作系统概述

学习路径:爬过这六个陡坡,你就能对Linux了如指掌

在这里插入图片描述

03 | 你可以把Linux内核当成一家软件外包公司的老板

操作系统其实就像一个软件外包公司,其内核就相当于这家外包公司的老板。将自己的角色切换成这家软件外包公司的老板,设身处地地去理解操作系统是如何协调各种资源,帮客户做成事情的。
在这里插入图片描述
在这里插入图片描述
从点击 QQ 图标,看操作系统全貌
1、输入设备–接待人员
鼠标和键盘是计算机的输入设备,在操作系统中,输入设备驱动其实就是客户对接员。有时候新插上一个鼠标的时候,会弹出一个通知你安装驱动,这就是操作系统这家外包公司给你配备对接人员呢。
2、输出设备–交付人员
显示器是输出设备,把计算机的处理结果呈现给客户。
显卡会有显卡驱动,在操作系统中称为输出设备驱动,可以比喻成"交付人员“。
3、中断事件
客户提需求时,客户希望外包公司把正在做的事情停下来,服务他,这时客户发送的需求被称为”中断事件“。当鼠标双击QQ时,会触发一个中断,这相当于客户告知对接员,我有新需求,需要你给处理下。你会事先把处理这种问题的方法教给客户端对接员,这在操作系统里就是调用中断处理函数。
4、程序-项目执行计划书
对于使用QQ,对外部公司来说,相当于接了个新业务,需要有一个项目执行计划书。内容就是,对于QQ程序来说,他能做哪些事,每件事怎样做,先做什么后做什么,把上面的逻辑都写到程序里,这个程序就相当于项目执行计划书。
5、文件管理系统
硬盘是个物理设备,要格式化成文件系统,才能存放程序。文件系统需要一个系统统一管理,这个系统成为文件管理系统。
6、程序&进程
QQ的二进制文件是静态的,成为程序。而运行起来的QQ,成为进程。
7、系统调用(System Call)
当多个进程想要用打印机来打印文件,他们不能打印到同一张纸上,否则第一行是A进程输出的内容,第二行是B进程输出的内容,这样就乱了。所以,打印机的行为是由操作系统内核来统一管理的,进程不能直接操作,这个由操作系统统一管理的就是系统调用。

系统调用会列出提供了哪些接口可以调用,然后进程在有需要的时候去调用。任何一个程序要运行起来,都需要通过系统调用来创建进程。
8、进程管理系统
在操作系统中,进程的执行也需要分配CPU来执行,所以,为了管理进程,我们还需要一个进程管理系统。如果运行的进程很多,则一个CPU会并发地运行多个进程,这就需要CPU的调度能力了。
9、内存管理系统
在操作系统中,不同的进程有不同的内存空间,这些内存空间需要统一的管理和分配,这就需要内存管理系统。

04 | 快速上手几个Linux命令:每家公司都有自己的黑话

在这里插入图片描述

05 | 学会几个系统调用:咱们公司能接哪些类型的项目?

在这里插入图片描述

1、Fork
在Linux里,要创建一个新的进程,需要一个老的进程调用fork来实现,这个老的进程叫做父进程,新的进程叫做子进程。
2、进程的内存空间
在操作系统里,每个进程都有自己的内存空间,不同进程之间互不干扰。

代码段(Code segment):对于进程空间,放程序代码的部分,称为代码段。

数据段(data segment):对于进程空间,存放进程运行中产生数据的部分,称为数据段。

堆(Heap):其中局部变量部分,在当前函数运行的时候起作用,当进入另一个函数时,这个变量就释放了;也有动态分配的,会较长时间保留,指明才销毁的,这部分内存空间称为“堆”。
3、brk和mmap
当内存分配数量较小时,用brk,会和原来的堆的数据连在一起。
当分配的内存较大时,使用mmap,会重新划分一块区域。
4、文件管理
Linux系统,一切皆文件:
1)启动一个进程,需要一个二进制文件。
2)启动进程时,需要加载一些配置文件如yml, properties等,这是文本文件
3)把日志打印到控制台上,是标准输出stdout文件
4)一个进程的输出作为另一个进程的输入,称为管道,管道也是一个文件
5)进程可以通过网络和其他进程通信,建立的socket,也是一个文件
6)进程需要访问的外部设备,也是一个文件
7)文件夹也是一个文件

每个文件,Linux都会分配一个文件描述符(File Descriptor),这是一个整数。有了这个文件描述符,我们就可以使用系统调用,查看或干预进程运行的方方面面。
5、信号处理 – 项目异常处理
通常进程中断,需要发送一个信号(signal),经常遇到的情况如下:
1)“Ctrl + C", 执行的命令终止退出
2)非法内存访问
3)硬件故障
4)用户进程通过kill函数,将信号发给另一个进程
6、进程间通信 – 项目组间沟通
1)消息队列:当两个进程需要交互的消息内容小的情况
2)共享内存:当两个进程需要交互的信息量比较大,用共享内存方式,可通过shmget创建一个共享内存块,通过shmat将共享内存映射到自己的内存空间,就可以读写了。

但是,当两个进程共同访问同一个内存中的数据时,就会存在竞争的问题。解决方式就是”排他“,通过信号量机制Semaphore。

Semaphore机制简介:对于只允许一个人访问的需求,可将信号量设为1。当一个人要访问时,先调用sem_wait,这时如果没有人在访问,则他就占用这个信号量,他就可以开始访问了;如果此时也有另一人要访问,也调用了sem_wait。这时后一人必须等待前一人访问完才能访问。当一人访问完成后,会调用seg_post将信号量释放,下一个等待的人就可以访问这个资源了。
7、网络通信-- 公司间沟通
不同机器间通过网络通信才能交互,交互时通过遵循相同的网络协议,如TCP/IP。
网络服务是通过Socket提供服务的,Socket可以理解为”插口“,在通信之前,双方要建立一个Socket。Socket也是一个文件,也有一个文件描述符,也可以通过读写函数进行通信。
8、Glibc – 中介
Glibc是Linux下使用开源的标准C库,Glibc为程序员提供丰富的API,除了如字符串处理、数学运算等用户态服务外,还封装了操作系统提供的系统服务,即系统调用的封装。

二、Linux核心原理:系统初始化

06 | x86架构:有了开放的架构,才能打造开放的营商环境

在这里插入图片描述
计算机硬件图:
在这里插入图片描述
CPU:对计算机来讲,CPU就是大脑,他是真正干活的,所有设备的执行都围绕他展开。

总线(Bus):CPU和其他设备连接,通过总线,其实就是主板上密密麻麻的集成电路,这些组成了CPU和其他设备的高速通道。

内存:在所有设备中,最重要的是内存(Memory),因为单靠CPU是无法完成计算任务的,很多复杂的计算需要把中间结果保持起来,然后基于中间结果做进一步的计算,所以CPU要依赖于内存。

总线上还有一些其他设备,例如显卡会连接显示器,磁盘控制器会连接硬盘,USB控制器会连接键盘和鼠标等。

CPU也不是单纯的一块,他包括三个部分:运算单元、数据单元、控制单元。
1)运算单元:只管计算,不管结果存哪里
2)数据单元:如果中间结果都存到数据里,那么每次计算都要经过总线去内存中拿,这太慢了,所以有了数据单元。数据单元包括CPU内部的缓存和寄存器组,空间很小,但速度飞快,可以暂时存放数据和运算结果。
3)控制单元:用来指挥到底做什么运算。他是一个统一的指挥中心,他可以获得下一条指令,然后执行这条指令。这个指令会知道运算单元取出数据单元中的某几个数据,计算出结果,然后放在数据单元的什么地方。
在这里插入图片描述
程序运行过程中要操作的数据和产生的计算结果,都会放在数据段里面。那CPU怎么执行这些程序,操作这些数据,产生一些结果,并写入到内存呢?

CPU的控制单元里面,有一个指令指针寄存器,他里面存放的是下一条指令在内存中的地址。控制单元会不停地将代码段指令拿进来,先放入指令寄存器。

当前的指令分两部分:一部分是做什么操作,如加法还是位移,一部分是操作哪些数据。

要执行这条指令,要把第一部分交个运算单元,第二部分交给数据单元。

数据单元根据数据的地址,从数据段里面读到数据寄存器里,就可以进行运算了。运算单元昨晚运算,产生的结果会暂存在数据单元的数据寄存器里。最终,会有指令将数据写回到内存中的数据段。

那么,怎样区分进程A和进程B呢?CPU里有两个寄存器,专门保持当前处理进程的代码段的起始地址,以及数据段的起始地址。这里面写的都是进程A,那当前执行的就是进程A的指令,等切换成了进程B,就会执行B的指令了,这个过程是进程切换。

CPU和内存直接传数据,靠的是总线。

当系统刚刚启动的时候,CPU 是处于实模式的,这个时候和原来的模式是兼容的。也就是说,哪怕你买了 32 位的 CPU,也支持在原来的模式下运行,只不过快了一点而已。

当需要更多内存的时候,你可以遵循一定的规则,进行一系列的操作,然后切换到保护模式,就能够用到 32 位 CPU 更强大的能力。
CPU 如何从启动开始,逐渐从实模式变为保护模式的?先按下不表,且听下回分说!

15 | 调度(上):如何制定项目管理流程?

在这里插入图片描述
这一节我们讲了调度相关的数据结构,还是比较复杂的。一个 CPU 上有一个队列,CFS 的队列是一棵红黑树,树的每一个节点都是一个 sched_entity,每个 sched_entity 都属于一个 task_struct,task_struct 里面有指针指向这个进程属于哪个调度类。在调度的时候,依次调用调度类的函数,从 CPU 的队列中取出下一个进程。

这样整个运行的场景就串起来了,在每个 CPU 上都有一个队列 rq,这个队列里面包含多个子队列,例如 rt_rq 和 cfs_rq,不同的队列有不同的实现方式,cfs_rq 就是用红黑树实现的。

当有一天,某个 CPU 需要找下一个任务执行的时候,会按照优先级依次调用调度类,不同的调度类操作不同的队列。当然 rt_sched_class 先被调用,它会在 rt_rq 上找下一个任务,只有找不到的时候,才轮到 fair_sched_class 被调用,它会在 cfs_rq 上找下一个任务。这样保证了实时任务的优先级永远大于普通任务。

16丨调度(中):主动调度是如何发生的?

在这里插入图片描述
一个运行中的进程主动调用 __schedule 让出 CPU。在 __schedule 里面会做两件事情,第一是选取下一个进程,第二是进行上下文切换。而上下文切换又分用户态进程空间的切换和内核态的切换。
主动调度,就是进程运行到一半,因为等待 I/O 等操作而主动让出 CPU,然后就进入了我们的“进程调度第一定律”。所有进程的调用最终都会走 __schedule 函数。

17 | 调度(下):抢占式调度是如何发生的?

在这里插入图片描述
整个进程的调度体系都放在里面。

这个脑图里面第一条就是总结了进程调度第一定律的核心函数 __schedule 的执行过程,这是上一节讲的,因为要切换的东西比较多,需要你详细了解每一部分是如何切换的。

第二条总结了标记为可抢占的场景,第三条是所有的抢占发生的时机,这里是真正验证了进程调度第一定律的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值