小林coding操作系统总结


前言

记录小林的图解系统部分重点知识,方便日后翻阅回看。
不一定面面俱到,也不会尽数记录,多半将需要辨析和对比的内容采用自己理解的方式来记录。
来源:小林coding


名词科普

MMU:MemoryManagementUnit内存管理单元,负责虚拟地址和物理地址的转换。
OOM:Out of Memory内存溢出。OOM Killer机制是一种保护进程手段
PCB:process control block 进程控制块,包括进程标识符、优先级、进程状态和虚拟地址信息等。
IPC:Inter-Process Communication,进程间通信
VFS:Virtual File System,虚拟文件系统,Linux在用户层和文件系统之间的中间层
DMA:Direct Memory Access 直接存储器访问。不需要依赖大量中断,使得设备在CPU不参与的情况下自行把I/O数据放入内存


前置一、硬件结构

1.1 计算机基本结构

冯诺依曼模型

名字特点
寄存器存储计算时的数据,因为内存离CPU太远了,寄存器会快很多
逻辑运算单元负责计算
控制单元负责控制CPU工作
总线负责CPU和内存及其他设备的通信
内存基本单位是字节,线性存储
输入输出设备控制总线与CPU连接

硬件的 64 位和 32 位指的是 CPU 的位宽

32位CPU64位CPU
寻址范围:最大操作4GB内存寻址范围:2^64
最好搭配32位宽的线路,一次只能计算不超过32位数字只有当一次计算超过 32 位数字才有优势

软件的 64 位和 32 位指的是指令的位宽
32位指令 + 兼容机制 -->可在64位机器上执行
64位指令不可再32位及其执行,因为32位寄存器放不下64位指令
操作系统也是一种程序,XX位操作系统即XX位软件

1.2 存储器层次结构

存储器

层级特点
寄存器
L1 CacheCPU独有,分为指令和数据,SRAM
L2 CacheCPU独有,SRAM
L3 Cache多CPU共用,SRAM
内存DRAM(动态存储芯片)
SSD&HDD固态硬盘和机械硬盘

1.3 提升缓存命中率,提高CPU速度

读取过程

Cache Line(缓存块) = Index索引 + Valid bit有效位 + Tag(头标志) + Data Block(数据块)

CPU访问内存地址

  1. 已知内存地址索引,得到CPU Cache Line 的 Index
  2. 判断有效位Valid,无效则访问内存
  3. 将内存和Cacheline的组标记Tag比较,不同则访问内存
  4. 根据内存的偏移量Offset访问数据块

总结: 读取数据的时候先访问Cache;有数据就读取;无数据则把内存的读入到Cache再读取

提升缓存命中率

  1. 数据缓存:按内存布局顺序访问,如for(i)外for(j)内
  2. 指令缓存:CPU分支预测器预测未来的指令,提前放入指令缓存;所以先排序后遍历会更快,或者用likely包裹if表达式手动预测
  3. 多核CPU:把线程绑在一个CPU核心上

1.4 缓存一致性

CPU的数据入方式

方式特点
写直达数据写入Cache Block后,并写入内存
(性能较差)
写回数据存在Cache时,写入Cache并标记为脏,不写入内存;
如果存放的是“别的内存地址的数据”则写入并标记为脏,如果此前这个数据是脏的,还需要将它写回到内存

只有 缓存不命中 && Cache为脏 才写入内存中;如果大量操作命中缓存则基本不需要读写内存,性能比写直达高很多

缓存一致性(多核心)

场景:A号CPU处理了变量i,但只是在Cache标记为脏;B号核心从内存读取了错误的i变量。

要想实现缓存一致性,关键是要满足 2 点

机制特点具体实现
写传播某个 CPU 核心发生写入操作时,需要把该事件广播通知给其他核心总线嗅探CPU监听总线的活动并广播
事物的串行化各核心看到的数据变化顺序是相同的基于总线嗅探的MESI协议已修改 / 独占 / 共享 / 已失效

MESI流程:

  1. A读取i的值,其他CPU没有缓存,标记为独占
  2. B读取i的值,广播给其他CPU核心,A返回读取信息,Cache Line状态为共享
  3. A修改i,首先广播令其他核心标记已失效,A标记已修改,此时Cache和内存数据不一致
  4. A再修改i,直接修改即可
  5. A的Cache里的i要被替换,是已修改状态,需要首先同步到内存

1.5 伪共享和CPU线程调度

伪共享

问题: 多个线程同时读写同一个 Cache Line 的不同变量时,而导致 CPU Cache 失效的现象。
解决: 内存对齐,通过空间换时间。

CPU选择线程

调度类调度器调度策略原则
Deadline(实时)Deadline调度器SCHED_DEADLINE按deadline有限
Realtime(实时)RT调度器SCHED_FIFO
SCHED_RR
对相同优先级的按FIFO / RR
Fair(普通)CFS调度器(完全公平)SCHED_NORMAL
SCHED_BATCH
为每个任务安排虚拟时间vruntime,运行越久就越大;
调度的时候优先vruntime少的任务

1.6 中断

为了避免中断处理时间过长,影响进程调度,Linux 将中断处理分为上半部和下半部:

名称特点
上半部对应硬中断,由硬件触发中断,用来快速处理中断
下半部对应软中断,由内核触发中断,用来异步处理上半部未完成的工作

1.7 0.1 + 0.2 != 0.3

负数的二进制表示方式

补码:把正数的二进制全部取反再 + 1

用了补码的表示方式,对于负数的加减法操作,实际上是和正数加减法操作一样的;否则还要将加减法反转。

计算机存小数

符号位指数位尾数
0 / 1小数点移到第一个有效数字后;移动位数+偏移量(float里是127)小数点右侧的数字

二进制浮点数的小数点左侧只能有 1 位,并且还只能是 1,既然这一位永远都是 1,那就可以不用存起来了,尾数还能多存一位小数。

前置二、操作系统结构

什么是内核? 内核作为应用连接硬件设备的桥梁,应用程序只需关心与内核交互,不用关心硬件的细节。

在这里插入图片描述
内核程序执行在内核态,用户程序执行在用户态。当应用程序使用系统调用时,会产生一个中断。发生中断后, CPU 会中断当前在执行的用户程序,转而跳转到中断处理程序,也就是开始执行内核程序。内核处理完后,主动触发中断,把 CPU 执行权限交回给用户程序,回到用户态继续工作。

OS内核架构可执行文件
Linux宏内核;内核是一个完整的可执行程序,且拥有最高权限。系统内核的所有模块(内存、进程、文件、设备)都运行在内核态ELF可执行文件链接格式
Windows混合内核 = 宏内核 + 微内核
微内核架构的内核只保留基本能力,驱动和文件等放在用户空间,服务之间隔离,但频繁切换有损性能
PE可移植执行文件

前置三、网络系统

一、内存管理

1.1 虚拟内存

直接操作物理地址行不通 ×,因为同地址写入新值会擦除内容。

操作系统会提供一种机制,将不同进程的虚拟地址和不同内存的物理地址映射起来。程序要访问虚拟地址的时候,由操作系统转换成不同的物理地址,这样不同的进程运行的时候,写入的是不同的物理地址,这样就不会冲突了

进程的虚拟地址----------------MMU---------->硬件物理地址

内存分段

如何映射?
虚拟地址包括段号(段表的索引)和段内偏移量
       |            /
       |           /
      指向         +
       |         /
       ↓        /
      段表----->1. 段的基地址 = 物理内存地址
        ------>2. 段界限

  1. 代码段
  2. 堆段
  3. 数据段
  4. 栈段

内存分页

虚拟地址包括页号(页表的索引)和页内偏移量
       |            /
       |           /
      指向         +
       |         /
       ↓        /
      页表----------> 物理页号 = 物理内存地址

分段分页
优点产生连续内存空间无外部碎片
缺点1. 内存碎片
2. 内存交换效率低(交换的程序占内存很大)
页内部内存碎片(最少分配一页)
32位4GB虚拟地址空间,如果每个页表项4字节,则需要4MB空间存储页表,(多级页表解决)

多级页表
单级页表:页号----->页表中的物理页号
多级页表:一级页号—>二级页表(页号)地址—>二级页表的物理页号
在需要时才创建二级页表,单级页表4MB,假如只有20%被用到,那么页表占用的内存空间只有4KB(一级页表) + 20%*4MB =0.804MB

TLB(Translation Lookaside Buffer):页表缓存 / 快表

段页式

  1. 先访问段表,得到页表的起始地址;
  2. 访问页表,得到物理页号
  3. 物理页号+页内位移 = 物理地址

虚拟内存作用

  1. 可以使运行内存超过物理内存大小。 因为CPU 访问内存的重复访问性,对于不经常用的内存,可以换到磁盘
  2. 解决多进程之间地址冲突的问题。 每个进程都有自己的页表且私有,虚拟内存空间相互独立。进程也没有办法访问其他进程的页表
  3. 提供了更好的安全性。页表项中除了物理地址之外,还有一些页的读写权限和存在等信息

1.2 Linux内存管理

Linux 内存主要采用的是页式内存管理,但同时也不可避免地涉及了段机制

在这里插入图片描述
虽然每个进程都各自有独立的虚拟内存,但是每个虚拟内存中的内核地址,其实关联的都是相同的物理内存。这样,进程切换到内核态后,就可以很方便地访问内核空间内存。

Linux的虚拟地址空间中的用户空间

内存段内容
栈段局部变量和函数调用上下文,一般8MB
文件映射段动态库共享内存;动态分配
堆段动态分配的内存,向上增长
未初始化数据 .bss未初始化的静态变量
已初始化数据 .data静态常量全局变量
程序文件 .text二进制可执行代码

1.3 malloc原理

malloc不是系统调用而是C库的函数,用于动态分配内存。

系统调用原理阈值free内存缺点
brk()堆顶指针向高地址移动分配内存小于128KB不归还,保留在内存池中下次直接复用频繁malloc和free产生内存碎片,导致内存泄漏
mmap()在文件映射区分配内存大于128KB释放内存
  1. malloc分配的是虚拟内存,如果没有被访问就不会映射和占用物理内存
  2. 预分配更大内存,1字节实际申请了132K字节。
  3. free多大内存?malloc返回给用户态的地址堆空间起始地址多了16字节,用于保存描述信息以便free知道内存块大小

1.4 内存回收机制

内存分配

访问分配的虚拟内存时没有映射到物理内存,会缺页中断,进入内核态调用缺页中断函数处理

  • 有空闲物理内存,直接分配
  • 无空闲内存,会进行回收内存
回收机制特点
后台内存回收异步,不阻塞线程
直接内存回收如果异步回收跟不上申请内存的速度,就直接回收,同步阻塞进程
  • 还无法满足,则触发OOM(Out of Memory)机制,一直杀死物理内存占用高的进程直到空间足够

回收范围

  1. 文件页。包括内核缓存的磁盘数据文件数据;干净页直接是否,脏页写回磁盘
  2. 匿名页。如堆、栈数据等,没有实际载体,所以swap写到磁盘中再释放

均基于LRU算法

性能影响

回收操作频繁–>磁盘IO次数多,会很卡,优化方式如下:

  1. 调整文件页和匿名页回收倾向。文件页影响小,因为干净页回收不发生磁盘IO
  2. 尽早触发异步回收。页高阈值页低阈值最小阈值。如果超过页低阈值,触发异步内存回收,但不阻塞;如果超过最小阈值则直接内存回收。调整阈值(三个阈值同时调整),要性能好就增大(提前触发异步),要内存使用大就调小

如何不被OOM杀掉

对进程打分,打分高的会被杀掉。页面数越多、或校准值oom_score_adj越高,得分越高,可以将oom_score_adj调低(默认0,最低-1000),不容易被杀掉。

1.5 4GB物理内存机器申请8G内存

  • 32 位操作系统 + 4GB物理内存。因为进程最大只能申请 3 GB 大小的虚拟内存,申请 8G 内存失败
  • 64 位操作系统 + 4GB物理内存。可申请128TB的虚拟内存。可以申请8GB的虚拟内存,如果没有被使用,完全没有问题,如果被使用的话,要看系统有没有swap分区(把磁盘当成内存来使用,负责换入换出):
    • swap分区:正常运行
    • swap分区:物理空间不够,发生OOM

二、进程调度

2.1 进程线程基础知识

进程: 运行中的可执行文件

在这里插入图片描述
PCB:进程控制块。把相同状态的进程链在一起,例如就绪队列阻塞队列,可以灵活插入和删除。

CPU上下文切换包括如下:

  1. 进程上下文切换
  2. 线程上下文切换
  3. 中断上下文切换
切换内容位置
CPU上下文切换CPU寄存器程序计数器
前者存储计算时的数据,后者存储指令位置
进程的上下文切换保存在PCB,包括虚拟内存、栈、全局变量等用户空间资源
也包括内核堆栈和寄存器等内核空间资源
内核管理,所以发生在内核态
线程的上下文切换不同进程:和进程上下文切换一样
同一进程:虚拟内存不动,只切换栈和寄存器等私有数据
内核态

线程: 进程当中的一条执行流程,并发运行且共享地址空间
分类:

用户线程内核线程轻量级线程LWP
位置TCB在用户态的线程管理库实现,操作系统看不到TCB,只看得到PCBTCB放在操作系统里内核支持的用户线程
优点没有内核态切换,速度快系统调用阻塞不影响其他内核线程
多线程的进程获得更多CPU运行时间
缺点如果线程因系统调用阻塞,那么其他线程不能执行
用户态线程没法打断运行的线程,只能主动交出CPU使用权
线程的创建切换和终止由系统调用,系统开销大

进程和线程的区别:
《进程和线程的探讨》

进程线程
概念运行中的可执行文件进程当中的一条执行流程,并发运行且共享地址空间
基本单位资源分配的单位CPU调度的单位
资源分配拥有完整资源平台只独享寄存器和栈
开销上下文切换开销大减少并发执行的时间和空间开销,具体体现在
创建和终止时间快;同进程内切换时间快;通信效率更高
优点编程容易
一个进程崩溃不影响其他进程
创建速度快
开销小
缺点开销大一个线程崩溃时会导致所有线程崩溃

2.2 进程调度

系统调度需要考虑的因素(原因):

  1. CPU利用率:IO请求阻塞时,CPU要从就绪队列运行一个进程
  2. 吞吐率:单位时间完成进程数
  3. 等待时间:就绪队列中进程的等待时间
  4. 响应时间:对于交互性应用(鼠标键盘)所考虑
名称算法适用范围
先来先服务FCFS先来后到长作业有利,适用于CPU繁忙型,不适用IO繁忙型
最短作业优先SJF优先短作业短作业有利
高响应比优先HRRN优先权 = 等待时间 + 要求时间 要求时间 {等待时间 + 要求时间\over 要求时间} 要求时间等待时间+要求时间无法预知要求时间,是理想
时间片轮转RR20ms-50ms最简单公平
多级队列反馈Multilevel Feedback Queue每个队列不同优先级,第一级按照FCFS,没完成转入第二级队尾,有高优先级的立马响应兼顾长短作业

2.3 进程间通信

方式特点创建优劣
匿名管道本质文件但没有文件实体;限父子 / 兄弟进程;半双工;内核态切换;单向字节流;生命周期和进程同在|、int pipe(int fd[2])效率低,不适合频繁交换
有名管道有文件实体;无需亲缘关系;内核态切换;生命周期和进程同在命令:mkfifo
函数:int mkfifo()
不相关进程也可以通信
共享内存多进程共享物理内存同一块区域shmget()内核态切换;但可能会有冲突
信号量为了防止多进程竞争共享资源
互斥:同一时刻只有一方访问临界区
同步:存在前后依赖关系
信号量类型sem_t
相关函数sem_...
主要用于互斥&同步
信号事件发生时对进程的通知机制,类似于中断,是异步通信ctrl + C SIGINT终止进程
ctrl + Z SIGSTOP进程被挂起
kill -9 PID SIGKILL杀死任何进程
SIGCHLD子进程结束时发出的信号
SIGKILLSIGSTOP不能被捕捉
唯一异步通信机制
Socket可基于TCP、UDP和本地进程通信int socket(协议族,通信协议,0)跨网络通信
消息队列内核中的消息链表。虽然解决了管道的效率问题,但通信不及时、大小有限制;生命周期和内核同在,除非手动关闭效率比管道高
内存映射磁盘文件映射到内存void* mmap()
int munmap()

共享内存和内存映射的区别:

  1. 共享内存可以直接创建;后者需要磁盘文件
  2. 进程操作同一块共享内存;后者在虚拟空间有独立内存
  3. 数据安全:进程突然退出:共享内存还在,后者消失
         电脑死机:共享内存没了,由于磁盘还在所以后者还在
  4. 生命周期:进程退出,共享内存还在,要标记删除;后者在进程退出后销毁

2.4 线程安全问题

临界区:访问共享资源的代码片段,不能给多线程同时执行
互斥:一个线程执行时,其他线程禁止进入临界区。好比「A 和B 不能在同一时刻执行」
同步:相互制约的等待与互通信息。好比「A应该在B之前执行」

互斥锁信号量条件变量
功能互斥互斥、同步满足条件时阻塞或解除阻塞,配合互斥量使用
函数锁类型pthread_mutex_t
函数pthread_mutex_...
信号量类型sem_t
函数sem_...
条件变量类型pthread_cond_t
函数pthread_cond_...

条件变量cont_t的必要性:如果没有条件变量的话,在没有物品时消费者循环查询是否有物品剩余,不停加锁和解锁,是一种资源浪费;条件变量设置wait时包含了锁mutex,调用pthread_cond_wait()时会先解锁并阻塞,生产生产一个后,用signal()通知这边解除阻塞,这边重新加锁并操作。《互斥锁为什么还要和条件变量配合使用》

悲观锁
《pthread 中各种锁的区别》

悲观锁互斥锁自旋锁读写锁
类型pthread_mutex_tpthread_spinlock_tpthread_rwlock_t
底层内核实现,失败时内核将线程置为“睡眠”,释放后唤醒用户态,开销小写锁 - 独占锁
读锁 - 共享锁
加锁失败失败时被阻塞,且线程切换;堵塞线程从用户->内核,存在两次线程上下文切换的开销一直忙等循环
适用场景锁住代码较长锁住代码短;
异步、协程等用户态编程方式
单核CPU必须要抢占式调度器,因为自旋的线程不会放弃CPU
读多写少

乐观锁(无锁编程)
先修改完共享资源,再验证这段时间内有没有发生冲突,如果没有其他线程在修改资源,那么操作完成,如果发现有其他线程已经修改过这个资源,就放弃本次操作。

生产者消费者问题

描述:

  • 缓冲区空时,消费者必须等待生产者生成数据;缓冲区满时,生产者必须等待消费者取出数据。(同步
  • 任何时刻,只能有一个生产者或消费者可以访问缓冲区;(互斥

解决:
创建一个互斥量mutex
创建一个生产者信号量psem,表示还有多少空位可生产,初始化为n。(如果没有上限,那么一个信号量就够了)
创建一个消费者信号量csem,表示库存数,初始化为0

生产者:

producer() {
     sem_wait(&psem);	生产前先生产额度-1,如果为0就阻塞
     pthread_mutex_lock(&mutex);
     ...
     pthread_mutex_unlock(&mutex);
     sem_post(&csem)	库存+1
}

消费者:

customer() {
     sem_wait(&csem);		库存-1,如果为0阻塞
     pthread_mutex_lock(&mutex);
     ...
     pthread_mutex_unlock(&mutex);
     sem_post(&psem)		生产额度+1
}

2.5 死锁

死锁的四个条件

  1. 互斥
  2. 持有并等待:等待访问资源2的时候并不会释放持有的资源1
  3. 不可剥夺:释放后才能获取
  4. 环路等待

避免:破坏一个条件即可,通常是资源有序分配法

2.6 页面置换和磁盘调度算法

页面置换

将页面从磁盘调入物理内存

名称算法适用范围
最佳页面置换算法OPT置换未来最长时间不访问的理想算法,衡量效率
先进先出~FIFO置换驻留时间长的短作业有利
最近最久未使用LRU置换最久没访问的效率高但开销大,需要每次更新频率链表,因此较少使用
最不常用LFU置换访问次数最少的计数器成本也不低;只考虑频率没考虑时间

磁盘调度(寻道)

名称算法适用范围
先来先服务FCFS按请求序列顺序分散、性能差
最短寻道时间优先SSF优先最近的磁道小区域来回移动
扫描scan
循环扫描Cscan
左右来回(到头);
单向(到头);
中间的占便宜;
会更平均;
LOOK
CLOOK
左右来回(不到头);
单向(不到头);

三、文件系统

3.1 文件的存储

名称优点缺点备注
连续空间存放读写效率高磁盘空间碎片、文件长度不易扩展需提前知道文件大小
隐式链表(非连续)无法直接访问数据块;稳定性较差文件头包含第一块和最后一块数据块位置,每个数据块都有指向下一块的指针,
显式链表(非连续)因为表保存在内存中,减少了磁盘访问次数,提高了检索速度不适用大磁盘,表太占空间内存中,每个磁盘块的指针放在一张表中,整个磁盘一张表
索引(非连续)无碎片;增删方便;支持随机读写开销大每个文件都有「索引数据块」,里面是指向文件数据块的指针列表

Unix文件存储:
对于小文件直接查找;对于大文件采用多级索引,需要大量查询。

3.2 空闲空间管理

名称优点缺点备注
空闲表法少量空闲区效果好大量小的空闲区查询效率低表内容包括第一个块号和块个数
空闲链表法不能随机访问,不适用大型文件系统
位图法二进制数字表示空闲

3.3 软链接和硬链接

给文件取别名内容
软连接多个目录项索引指向一个文件,不可跨文件系统,删除所有硬链接及源文件后才彻底删除该文件
硬链接重新创建一个文件,具有inode,文件存储的是另一个文件的路径,所以可以跨文件系统

3.4 文件I/O

分类区别具体
缓冲与费缓冲I/O是否利用标准库缓冲缓冲:通过标准库缓存实现加速访问,到了输入或输出时标准库再系统调用,减少次数
非缓冲:直接系统调用
直接与非直接I/O是否利用操作系统的缓存(默认非直接)直接:无内核缓存复制,直接经过文件系统访问磁盘
非直接:读时,数据从内核缓存拷贝给程序;写时,数据从程序拷贝给内核,再由内核决定什么时候写入磁盘
阻塞与非阻塞I/O是否等待 内核数据准备好&&数据从内核态拷贝到用户态阻塞:read时等待 内核数据准备好 && 从内核缓冲区拷贝到程序缓冲区,才返回
非阻塞:read立即返回,程序不断轮询内核,直到上述条件满足才获取结果
同步与异步I/O同步调用:阻塞、非阻塞、多路复用都属于同步,因为都要等数据从内核态拷贝到用户态
异步:发起aio_read立即返回,内核自动拷贝到程序空间

《标准IO库的缓冲区》

四、设备管理

CPU通过读写设备控制器中的寄存器,来控制设备,相当于一个小CPU

寄存器:

  1. 数据寄存器:CPU 向 I/O 设备写入需要传输的数据前,先发送一个 H 字符给到对应的 I/O 设备。
  2. 命令寄存器:CPU 发送一个命令,告诉 I/O 设备,要进行输入/输出操作,于是就会交给 I/O 设备去工作,任务完成后,会把状态寄存器里面的状态标记为完成。
  3. 状态寄存器:目的是告诉 CPU ,现在是否在工作,直到状态寄存标记成已完成,CPU 才能发送下一个字符和命令。

设备可分为块设备:数据存储在固定大小的块中,如硬盘USB
    和字符设备:以字符为单位接发字符流,不可寻址。

数据缓冲区:减少对设备的频繁操作
CPU 写入数据到控制器的缓冲区时,当缓冲区的数据囤够了一部分,才会发给设备。
CPU 从控制器的缓冲区读取数据时,也需要缓冲区囤够了一部分,才拷贝到内存。

I/O控制方式

  1. 轮询:CPU一直查寄存器的状态标记位
  2. 中断:设备完成任务后触发中断到中断控制器,通知CPU停下来处理。
    (1)软中断,例如调用INT指令触发
    (2)硬件中断,硬件通过中断控制器触发

中断对于磁盘频繁读写数据,不友好,解决方法是DMA
DMA:Direct Memory Access 直接存储器访问。不需要依赖大量中断,使得设备在CPU不参与的情况下自行把I/O数据放入内存

  1. CPU对DMA控制器下指令,告诉它读多少、读完放在内存哪里
  2. DMA控制器向磁盘控制器发出命令;磁盘传输到内存后通知DMA
  3. DMA控制器中断通知CPU指令完成,CPU可以用内存里的数据了

设备驱动程序

设备控制器属于硬件;为了减少设备控制器的差异,引入设备驱动程序,属于操作系统的一部分,会提供接口给操作系统,方便OS通过调用设备驱动程序的接口来控制设备控制器
另外,设备驱动程序也会调用中断处理程序中断处理函数来处理中断

通用块层

通用块层用来管理不同块设备,具有以下功能:

  1. 向上为文件系统和应用程序,提供访问块设备的标准接口,向下把各种不同的磁盘设备抽象为统一的块设备,并在内核层面,提供一个框架来管理这些设备的驱动程序
  2. I/O调度

存储系统的I/O软件分层

Linux存储系统层次内容功能
文件系统层虚拟文件系统向上为程序提供文件访问接口
向下管理磁盘数据
通用块层块设备的I/O队列和调度器调度I/O发给设备层
设备层驱动程序、设备控制器、硬件设备物理设备的I/O操作

键盘敲入字母,发生了什么

在这里插入图片描述

  1. 键盘控制器扫描数据,缓冲在其寄存器中,并给CPU发送中断请求。
  2. CPU收到中断后,OS保存上下文,并调用中断处理程序(属于键盘驱动程序)
  3. 中断处理函数键盘控制器寄存器缓冲区找到字符,翻译成ASCII码(显示字符),并放入读缓冲队列
  4. 显示驱动程序把读缓冲队列数据放入写缓冲队列,最后写入到显示控制器的寄存器缓冲区中,并显示在屏幕上
  5. CPU回复上下文
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值