编程必备基础之操作系统
操作系统概述
操作系统是管理计算机硬件和软件资源的计算机程序,管理配置内存、决定资源供需顺序、控制输入输出设备等。操作系统提供让用户和系统交互的操作界面。操作系统的种类是多种多样的,不局限于计算机,从手机到超级计算机,操作系统可简单也可复杂,在不同的设备上,操作系统可向用户呈现多种操作。因为我们不可能直接操作计算机硬件,而且设备种类繁多,需要一个统一的界面,因此有了操作系统,操作系统的简易性使得更多人能使用计算机。常见的操作系统有:Windows、Linux、MacOS、Android等,总结一句话就是:操作系统是管理硬件、提供用户交互的软件系统。
- 操作系统的基本功能
- 操作系统统一管理着计算机资源。这些计算机资源包括处理器资源、存储器资源、IO设备资源和文件资源等。
- 操作系统实现了对计算机资源的抽象。即用户无需面向硬件接口编程;IO设备管理软件,提供独写接口;文件管理软件,提供操作文件的接口。
- 操作系统提供了用户和计算机之间的接口。例如图像窗口形式、命令行形式和系统调用形式等。
- 操作系统的相关概念
- 并发性:说到并发就不得不提一下并行性,并行性是指两个或多个事件可以在同一时刻发生,而并发性是指两个或多个事件可以在同一个时间间隔发生。
- 共享性:多个程序可以同时使用主存资源,资源共享根据属性分为互斥共享和同时访问两种形式
- 互斥共享形式:当资源被程序A占用时,其他想使用的话就只能等待,只有进程A使用完以后,其他进程才可以使用该资源。
- 同时访问形式:某种资源在一段时间内并发地被多个程序访问,这种“同时”是宏观的,从宏观去看该资源可以被同时访问
- 虚拟性:虚拟性表现为把一个物理实体转为若干个逻辑实体,物理实体是真实存在的,逻辑实体是虚拟的,虚拟的技术主要有时分复用技术和空分复用技术。
- 时分复用技术:资源在时间上进行复用,不同程序进行并发使用,多道程序分时使用计算机的硬件资源,提高资源的利用率
- 虚拟处理器技术:借助多道程序设计技术,为每个程序建立进程,多个程序分时复用处理器
- 虚拟设备技术:物理设备虚拟为多个逻辑设备,每个程序占用一个逻辑设备,多个程序通过逻辑设备并发访问
- 空分复用技术:空分复用技术用来实现虚拟磁盘、虚拟内存等,提高资源利用率,提高编程效率
- 虚拟磁盘技术:物理磁盘虚拟为逻辑磁盘,例如C、D、E等逻辑盘,使用起来更加安全方便
- 虚拟内存技术:在逻辑上扩大程序的存储容量,使用比实际内存更大的容量,大大提升编程效率
- 时分复用技术:资源在时间上进行复用,不同程序进行并发使用,多道程序分时使用计算机的硬件资源,提高资源的利用率
- 异步性:在多道程序环境下,允许多个进程并发执行,进程在使用资源时可能需要等待和放弃,进程的执行并不是一气呵成的,而是以走走停停的形式推进
- 并发性:说到并发就不得不提一下并行性,并行性是指两个或多个事件可以在同一时刻发生,而并发性是指两个或多个事件可以在同一个时间间隔发生。
进程管理
为什么需要进程呢?在没有配置OS(操作系统)之前,资源属于当前运行的程序,配置OS之后,引入多道程序设计的概念,可以合理的隔离资源、运行环境、提升资源利用率。进程是系统进行资源分配和调度的基本单位,进程作为程序独立运行的的载体保障程序正常运行,进程的存在使得操作系统资源的利用率大幅提升。
进程管理之进程实体
主存中得进程形态
- 标识符:标识符唯一标记一个进程,用户区别其他进程,如进程id
- 状态:标记进程的进程状态,如:运行态
- 程序计数器:指向进程即将被执行的下一条指令的地址
- 内存指针:程序代码,进程数据相关指针
- 上下文数据(重要):进程执行时处理存储器的数据
- IO状态信息:被进程IO操作时所占用的文件列表
- 记账信息:使用处理器时间、时钟数总和等。
由此可知,主存中的进程形态主要包括进程标识符,处理机状态,进程调度信息,进程控制信息等。其中进程控制块(PCB)是用于描述和控制进程运行的通用数据结构,记录进程当前状态和控制进程进行运行的全部信息,PCB使得进程成为能够独立运行的基本单位。PCB是操作系统进行调度经常会被读取的信息,而且是常驻内存的,存放在系统专门开辟的PCB区域内。
进程与线程
之前说过进程是操作系统进行资源分配和调度的基本单位,而线程是操作系统进行运行调度的最小单位,线程包含在进程之中,是进程中实际运行的工作单位,一个进程可以并发多个线程,每个线程执行不同任务。
进程 | 线程 | |
---|---|---|
资源 | 资源分配的基本单位 | 不拥有资源 |
调度 | 独立调度的基本单位 | 独立调度最小单位 |
系统开销 | 进程系统开销大 | 线程系统开销小 |
通信 | 进程IPC | 读写同一进程数据通信 |
一个进程可以有多个线程,一个进程中的线程共享资源,计算机对进程的调度,实际上是对进程中的线程进行调度 |
五状态模型
- 创建状态:创建进程时拥有PCB但其它资源尚未就绪的状态称为创建状态,操作系统提供fork函数接口创建进程。
- 就绪状态:当进程被分配到除CPU以外的所有必要资源后,只要再获得CPU的使用权,就可以立即运行。其他资源都转准备好、只差CPU资源的成为就绪状态。
- 在一个系统中处于就绪状态的进程通常排成一个队列,称为就绪队列。
- 在一个系统中处于就绪状态的进程通常排成一个队列,称为就绪队列。
- 执行状态:进程获得CPU,其程序正在执行称为执行状态,再单处理机中,在某个时刻只能有一个进程是处于执行状态。
- 阻塞状态:进程因某种原因如:其他设备未就绪而无法继续执行,从而放弃CPU的状态称为阻塞状态。
- 终止状态:程序执行完成。
进程同步
为什么需要进程间的同步呢?先让我们来看一个经典的问题:生产者-消费者问题
生产者-消费者问题:有一群生产者进程在生产产品,并将这些产品提供给消费者进程进行消费,生产者进程和消费者进程可以并发执行,在两者之间设置了一个具有n可缓冲区的缓冲池,生产者进程需要将所生产的产品放到一个缓冲区中,消费者进程可以从缓冲区取走产品消费
由上图我们可以看出,单从生产者程序或消费者程序去看是没问题的,但两者并发执行时就可能会出现差错。如下图:
这里的缓冲区就相当于临界资源。
再来看一个哲学家进餐问题:
有五个哲学家,他们的生活方式时是交替的进行思考和进餐,哲学家们共同使用一张圆桌子,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子。平时哲学家们只进行思考,饥饿时则试图取靠近他们的左、右两只筷子,只有两支筷子都被他拿到的时候才能进餐,进餐完毕后,放下左右筷子继续思考。
出现上图中的问题是什么呢?其根源问题是:彼此之间没有相互通信,如果“生产者通知消费者我已经完成了一件生产”,“哲学家向旁边哲学家说我要进餐了”,就不会出现上图中的问题了,也就是需要进程间的同步。
什么是进程同步呢?当对竞争资源在多个进程间进行使用次序的协调,使得并发执行的多个进程之间可以有效使用资源和相互合作。这里的竞争资源也就是上图中的临界资源,什么是临界资源?临界资源指的是一些虽作为共享资源,却又无法同时被多个线程共同访问的共享资源。当有进程在使用临界资源时,其他进程必须依据操作系统的同步机制,等待占用进程释放该共享资源,才可以重新竞争使用共享资源。
进程同步的原则:
- 空闲让进:资源五占用,允许使用
- 忙则等待:资源有占用,请求进程等待
- 有限等待:保证有限等待时间能够使用资源
- 让权等待:等待时,进程需要让出CPU
进程间同步的常用方法:如消息队列,共享存储,信号量。当多个线程并发使用进程资源时,进程内的多线程也需要,因为进程中的资源时进程中线程的共享资源。线程同步的方法有:互斥量、读写锁、自旋锁、条件变量等,这些方法是如何保证线程同步的呢?
- 互斥量:由于多个线程的指令交叉执行,而互斥量可以保证先后执行,即保证原子性。什么是原子性呢?原子性是指一系列操作不可被中断的特性, 这一系列操作要么全部执行完成,要么全部没有执行,不存在部分执行部分未执行的情况
- 互斥量是最简单的线程同步方法
- 互斥量(互斥锁),处于两态之一的变量:解锁和加锁
- 两个状态可以保证资源的串行
- 自旋锁:自旋锁也是一种多线程同步的变量,使用自旋锁的线程会反复检查锁变量是否可用,自旋锁不会让出CPU,是一种忙等待状态,即死循环等待锁被释放。
- 自旋锁避免了进程或线程上下文切换的开销
- 操作系统内部很多地方都是使用的自旋锁
- 自旋锁不适合在单核CPU中使用
- 读写锁:这种锁适用于临界资源多读少写,读取的时候并不会改变临界资源的值。
- 读写锁是一种特殊的自旋锁
- 允许多个读者同时访问资源以提高读的性能
- 对写的操作则是互斥的
- 条件变量
- 条件变量是一种相对复杂的同步方法
- 条件变量允许线程睡眠,直到满足某种条件
- 当满足条件时,可以向该线程发送信号,通知唤醒
同步方法 | 描述 |
---|---|
互斥锁 | 最简单的一种线程同步方法,会阻塞线程 |
自旋锁 | 避免切换的一种线程同步方法,属于“忙等待” |
读写锁 | 为“读多写少”的资源设计的线程同步方法,可以显著提高性能 |
条件变量 | 相对复杂的一种线程同步方法,有更灵活的使用场景 |
进程同步之共享内存 | |
在某种程度上,多进程是是共同使用物理内存的,由于操作系统的进程管理,进程间的内存空间是独立的,进程默认是不能访问进程空间之外的内存空间的 | |
共享内存就可以打破这个限制,因为有这个共享内存,不同进程就可以通过页表映射到同一个共享内存去,这个共享内存既可以被进程1使用,也可以被进程2使用。 | |
共享存储允许不相关的进程访问同一片物理内存,共享内存是两个进程之间共享和传递数据的最快方式,共享内存未提供同步机制,需要借助其他机制访问。通过共享内存同步的过程就是:申请共享内存->连接到进程空间->使用共享内存->脱离进程空间并且删除。共享内存是高性能后台开发中最常用的同步方式。 | |
进程同步之Unix域套接字 | |
域套接字是一种高级的进程间通信的方法,Unix域套接字可以用于同一台机器进程间通信。其运行过程是创建套接字->绑定(bind)套接字->监听(listen)套接字->接收&处理信息。域套接字提供了简单可靠的进程通信同步服务,只能在单机使用,不能跨机器使用。 |
Linux的进程管理
Linux进程的相关概念:
进程类型:
- 前台进程:前台进程就是具有终端,可以和用户交互的进程
- 后台进程:
- 与前台进程相对,没有占用终端的就是后台进程
- 后台进程基本上b不和用户交互,优先级比前台进程低
- 将需要执行的命令以“&”符号结束
- 守护进程(daemon):特殊的后台进程
- 很多守护进程在系统引导的时候启动,一直运行到系统关闭
- Linux系统有很多典型的守护进程。例如:crond,sshd,httpd,mysqld等,进程名字以“d”结尾的一般都是守护进程。
进程标记:
- 进程ID
- 进程ID是进程的唯一标记,每个进程拥有不同的ID
- 进程ID表现为一个非负整数,最大值由操作系统限定
- 操作系统提供fork()函数接口创建进程。例如进程A调用fork接口创建了进程B,进程B调用fork接口创建了进程C,那此时进程A和进程B就存在父子进程关系,进程A是父进程,进程B是子进程。进程的父子关系可以通过pstree命令查看。
ID为0的进程是idle进程,是系统创建的第一个进程,ID为1的进程init进程,是0号进程的子进程,完成系统初始化,Init进程是所有用户进程的祖先进程。
- 进程的状态标记
Linux中进程的状态如下:
状态符号 | 状态说明 |
---|---|
R | (TASK_RUNNING),进程正处于运行状态 |
S | (TASK_INTERRUPTIBLE),进程正处于睡眠状态 |
D | (TASK_UNINTERRUPTIBLE),进程正处于IO等待的睡眠状态 |
T | (TASK_STOPPED),进程正处于暂停状态 |
Z | (TASK_DEAD or EXIT_ZOMBIE),进程正处于退出状态,或僵尸进程 |
操作Linux进程的相关命令
- ps命令:ps命令常用于显示当前进程的状态,ps命令常配合aux参数或ef参数和grep命令检索特定进程
- top命令
- kill命令:kill命令发送指定信号给进程,kill-l可以查看操作系统所支持的系统
作业管理
作业管理之进程调度
进程调度是指计算机通过决策,决定哪个就绪进程可以获得CPU使用权。通俗来说就是保留旧进程的运行信息,请出旧进程(收拾包袱),选择新进程,准备运行环境并分配CPU(新驻进)。那么是如何进行进程的调度的呢?
- 就绪队列的排队机制:将就绪进程按照一定的方式排成队列,以便调度程序可以最快找到就绪进程。
- 选择运行进程的委派机制:调度程序以一定的策略选择就绪进程,将CPU资源分配给它
- 新老进程的上下文切换机制:保存当前进程的上下文信息,装入被委派执行进程的运行上下文
进程的调度方式分为抢占式调度和非抢占式调度。非抢占式调度是指处理器一旦分配给某个进程,就让该进程一直使用下去,调度程序不以任何原因抢占正在被使用的处理器,直到进程完成工作,或因为IO阻塞才会让出处理器;抢占式调度是指允许调度程序以一定的策略,暂停当前运行的进程,保存好进程的上下文信息,分配处理器给新进程。
抢占式调度 | 非抢占式调度 | |
---|---|---|
系统开销 | 频繁切换,开销大 | 切换次数少,开销小 |
公平性 | 相对公平 | 不公平 |
应用 | 通用系统 | 专用系统 |
进程调度算法 |
- 先来先服务调度算法
- 短进程优先调度算法:调度程序优先选择就绪队列中估计运行时间最短的进程;短进程优先调度算法不利于长作业进程的运行
- 高优先权优先调度算法:进程附带优先权,调度程序优先选择权最高的进程,高优先权优先调度算法使得 紧迫的任务可以处理
- 时间片轮转调度算法:按先来先服务的原则排列就绪进程,每次从队列头部取出待执行进程,分配一个时间片执行;是相对公平的调度算法,但不能保证及时响应用户
作业管理之死锁
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞现象,若无外力作用,他们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
死锁的产生
- 竞争资源:共享资源数量不满足各个进程需求,各个进程 之间发生资源竞争导致死锁,
- 进程调度顺序不当
死锁的四个必要条件: - 互斥条件:进程对资源的使用是排他性的使用,某资源只能由一个进程使用,其他进程需要使用只能等待
- 请求保持条件:进程至少保持一个资源,又提出新的资源请求,新资源被占用,请求被阻塞,被阻塞的进程不释放自己保持的资源
- 不可剥夺条件:进程获得的资源在未完成使用前不能被剥夺,获得的资源只能由进程自生释放
- 环路等待条件:发生死锁时,必然存在进程-资源环形链
死锁的处理 - 预防死锁的方法
- 摒弃请求保持条件:系统规定进程运行之前,一次性申请所有需要的资源,进程在运行期间不会提出资源的请求,从而摒弃请求保持条件
- 摒弃步课剥夺条件:当进程请求一个新的资源得不到满足时,必须释放占有的资源,当进程运行时占有的资源可以被释放,意味着可以被剥夺
- 摒弃环路等待条件:可用资源线性排序,申请必须按照需要递增申请,线性申请不在形成环路,从而摒弃了环路等待条件
- 银行家算法:银行家算法是一个可操作得著名得避免死锁得方法,以银行借贷系统分配策略为基础的算法。
- 客户申请的贷款是有限的,每次申请须声明最大资金量
- 银行家在能够满足贷款时,都应该给用户贷款
- 客户在使用贷款后,能够及时归还贷款。
根据还需要分配的资源表,对比可分配资源表,先给能够满足贷款的用户,给用户贷款,即图中的P2,P2使用完资源后,需要及时归还资源
存储管理
早期计算机编程并不需要过多的存储管理,随着计算机和程序越来越复杂,存储管理成为必要。
- 确保计算机有足够的内存处理处理数据
- 确保程序可以从可用内存中,获取一部分内存使用
- 确保程序可以归还使用后的内存,已供其他程序使用
存储管理之内存分配与回收
内存分配的过程
- 单一连续分配:单一连续分配是最简单的内存分配方式,只能在单一用户、单进程的操作系统中使用
- 固定分区分配:固定分区分配是支持多道程序的最简单的存储分配方式,内存空间被划分成若干个固定大小的区域,每个分区只提供给一个用户使用,互不干扰
- 动态分区分配:根据进程实际需要,动态分配内存空间,相关数据结构、分配算法如下:
- 动态分区空闲表数据结构:对空闲区进行标记,0表示空闲区,1表示已被使用
- 动态分区空间链数据结构
- 首次适应算法(FF算法):分配内存时从开始,顺序查找适合内存区,若没有合适的空闲区,则该次分配失败;每次从头部开始,使得头部地址不断被划分
- 最佳适应算法(BF算法):最佳适应算法要求空闲链表按照容量大小排序,遍历空闲链表找到最佳合适的空闲区
- 快速适应算法(QF算法):快速适应算法要求有多个空闲区链表,每个空闲区链表存储一种容量的空闲区
- 动态分区空闲表数据结构:对空闲区进行标记,0表示空闲区,1表示已被使用
内存回收的过程
情况一:不需要新建空闲链表节点,只需要把空闲区1的容量增大为空闲区即可;情况二:将回收区与空闲区合并,新的空闲区使用回收区的地址;情况三:将空闲区1、空闲区2和回收区合并,新的空闲区使用空闲区1的地址;情况四:为回收区创建新的空闲节点,插入到相应的空闲区链表中去。
存储管理之段页式存储管理
由于每个进程都有自己独立的进程空间,那操作系统是如何管理进程的空间呢?
- 页式存储管理:
- 将进程逻辑空间等分为若干大小的页面
- 相应的把物理内存空间分成与页面大小的物理块
- 以页面为单位把进程空间装进物理内存中分散的物理块
页表:页表记录了进程逻辑空间与物理空间的映射
现代计算机系统中,可以支持非常大的逻辑地址空间(\(2^{32}\)~\(2^{64}\)),这样,页表就变得非常大,要占用非常大的内存空间,如具有32位逻辑地址空间的分页系统,规定页面大小为4KB,则在每个进程页表中的页表项可达1M(32位系统进程的寻址空间为4G,4G/4KB=1M)个,如果每个页表项占用1Byte,故每个进程仅仅页表就要占用1M的内存空间。
- 段式存储管理
- 将进程逻辑空间划分成若干段(非等分)
- 段的长度由连续逻辑的长度决定
- 主函数MAIN,子程序段X,系函数Y等
段式存储和页式存储都离散地管理了进程的逻辑空间。页是物理单位,段是逻辑单位,分页是为了合理利用空间,分段是为了满足客户需求;页大小由硬件空间,段长度可动态变化;页表信息是一维的,段表信息是二维的。
- 段页式存储管理:由于分页可以有效提高内存利用率(虽然说存在内存碎片),分段可以满足用户需求,我们可以将两者结合,形成段页式存储管理。
- 先将逻辑空间按段式管理分成若干段
- 再把段内空间按页式管理等分成若干页
存储管理之虚拟内存
思考:一个游戏十几个G,物理内存只有4G,那这个游戏是如何运行起来的呢?
有些进程实际需要的内存很大,超过物理内存的容量,多道程序设计,使得每个进程可用物理内存更加稀缺,不可能无限增加物理内存,物理内存总有不够的时候,这个时候就需要虚拟内存了。虚拟内存是操作系统内存管理的关键技术,使得多道程序运行和大程序运行成为现实,把程序使用内存划分,将部分暂时不使用的内存放置在辅存。
程序的局部性原理:局部原理是指CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于集中在一个较小的连续区域中。
- 程序运行时,无需全部装入内存,装载部分即可
- 如果访问页不在内存,则发出缺页中断,发起页面置换
- 从用户层面看,程序拥有很大的空间,即是虚拟内存
- 虚拟内存实际是对物理内存的补充,速度接近于内存,成本接近于辅存
虚拟内存的置换算法:和我在《计算机组成原理》这篇博客中的高速缓存的置换策略差不多,这里就不详细介绍了。
- 先进先出算法(FIFO)
- 最不经常使用算法(LFU)
- 最近最少使用算法(LRU)
高速缓存的替换策略发生在Cache-主存层次,只要是为了解决速度问题;虚拟内存的替换策略发生在主存-辅存层次,主要是为了解决容量问题。
Linux的存储管理
Buddy内存管理算法
- Buddy算法是经典的内存管理算法
- 算法基于计算机处理二进制的优势具有极高的效率
- 算法主要是为了解决内存外碎片的问题
页内碎片:内部碎片是已经被分配出去(能明确指出属于哪个进程)的内存空间大于请求所需的内存空间,不能被利用的内存空间就是内部碎片。
页外碎片:外部碎片是指还没有被分配出去(不属于任何进程),但是由于大小而无法被分配给申请内存空间的新进程的内存空闲块。
Buddy是伙伴的意思,这里的”伙伴“指的是内存的”伙伴“,一片连续内存的”伙伴“是相邻的另一片大小一样的连续内存
Buddy内存管理算法执行过程:创建一系列空闲块链表,每一种都是2的幂 –> 现在需要分配100kb内存 –> 回收刚才分配的内存
Linux的交换空间
交换空间(Swap)是磁盘的一个分区,Linux物理内存满时,会把一些内存交换至Swap空间,Swap空间是初始化系统时配置的。
冷启动内存依赖:对于一些大型的应用程序,在启动的过程中需要使用大量的内存,但是这些内存很大一部分只是在启动的时候使用一下,在运行的时候很少使用到这部分内存,因此有了这个交换空间,系统就可以将这个部分不怎么使用的内存数据保存在SWAP空间中,从而释放跟多的物理内存,提供给这个系统使用。
系统睡眠依赖: 当Linux系统需要睡眠的时候,它就会把系统中的所有数据都保存在swap空间内,等下次这个系统需要启动的时候,才把这些数据重新加载到内存中里面,这样就可以加快系统的启动速度。
大进程空间依赖:有些进程确实需要使用大量的内存空间,但是物理内存不够使用,因此需要把这些进程需要使用的内存暂时保存到交换空间中,使得这个大的进程也可以运行起来
Swap空间和虚拟内存的对比:
— | Swap空间 | 虚拟内存 |
---|---|---|
存储位置 | Swap空间存在于磁盘 | 虚拟内存存在于磁盘 |
置换层次 | Swap空间与主存发生置换 | 虚拟内存与主存发生置换 |
所属概念 | Swap空间是操作系统概念 | 虚拟内存是进程概念 |
解决的问题 | Swap空间解决系统物理内存不足问题 | 虚拟内存解决进程物理内存不足的问题 |
操作系统的文件管理
文件的逻辑结构
- 逻辑结构的文件类型
- 有结构文件:例如文本文件、文档、媒体文件等
- 文件内容由定长记录和可变记录组成
- 定长记录存储文件格式、文件描述等结构化数据项
- 可变长记录存储文件具体内容等
- 无结构文件:例如二进制文件、链接库等
- 也称为流式文件,如exe文件、dll文件、so文件等
- 文件内容长度以字节为单位
- 有结构文件:例如文本文件、文档、媒体文件等
- 顺序文件
- 顺序文件是指按顺序存放在存储介质中的文件
- 磁带的存储特性使得磁带文件只能存储顺序文件
- 顺序文件是所有逻辑文件当中存储效率最高的
- 索引文件
- 可变长文件不适合使用顺序文件格式存储
- 索引文件是为解决可变长文件存储而发明的一种文件格式
- 索引文件需要配合索引表完成存储的操作
辅存的存储空间分配
- 辅存的分配方式
- 连续分配:顺序读取文件内容非常容易,速度很快,对存储要求高,要求满足容量的连续存储空间
- 链接分配:链接分配可以将文件存储在离散的盘块中,需要额外的存储空间存储文件的盘块链接顺序
- 隐式链接:隐式分配的下一个链接指向存储在当前盘块内,隐式分配适合顺序访问,随机访问效率低,可靠性差,任何一个链接出问题都会影响整个文件
- 显示链接:不支持高效的直接存储(FAT记录项多),检索时FAT表占用较大的存储空间(需要将整个FAT表加载到内存)
- 隐式链接:隐式分配的下一个链接指向存储在当前盘块内,隐式分配适合顺序访问,随机访问效率低,可靠性差,任何一个链接出问题都会影响整个文件
- 索引分配:把文件的所有盘块集中存储(索引),读取某个文件时,将文件索引读取进内存即可
每个文件拥有一个索引块,记录所有盘块信息,索引分配方式支持直接访问盘块,文件较大时,索引分配方式具有明显优势
- 存储空间管理
- 空闲表:空闲盘区的分配与内存的分配相似,首次适应算法、循环适应算法等,回收过程也与内存回收类似
- 空闲链表:空闲链表法把所有空闲盘区组成一个空闲链表,每个链表节点存储空闲盘块和空闲的数目
- 位示图:位示图维护成本很低,可以非常容易找到空闲盘块,位示图使用0/1比特位,占用空间小
目录管理
任何文件或目录都只有唯一路径。文件常见的描述信息有:文件标识符、文件类型、文件权限、文件物理地址、文件长度、文件连接计数、文件存取时间、索引节点编号、文件状态、访问计数、链接指针等。
Linux文件基本操作
Linux目录
目录 | 描述 |
---|---|
/bin | 存放二进制可执行文件(ls,cat,mkdir),常用的命令都在该目录下 |
/etc | 存放系统管理和配置文件 |
/home | 存放所有用户文件的根目录,使用户目录的基点,比如用户user的主目录就是/home/user |
/usr | 用户存放系统应用程序,比较重要的目录/usr/local本地系统管理员软件安装目录 |
/opt | 额外安装的可选应用程序包所放置的位置 |
/proc | 虚拟文件系统目录,是系统内存的映射,可直接访问这个目录来获取系统信息 |
/root | 系统管理员的主目录 |
/sbin | 存放二进制可执行文件,只有root才能当问 |
/dev | 用于存放设备文件 |
/mnt | 系统管理员安装临时文件系统的安装点,系统提供这个目录是让用户临时挂载其他的文件系统 |
/boot | 存放用于系统引导时使用的各种文件 |
/lib | 存放跟文件系统种的程序运行所需要的共享库及内核模块 |
/var | 用于存放运行时需要改变数据得文件 |
Linux文件常用操作
创建文件:touch file 修改文件:vim file 查看文件:cat file 删除文件:rm file 创建文件夹:mkdir dir 删除文件夹:rm dir/ 该方式会提示,不能删除文件夹 递归删除文件夹:rm -r dir/ 进入文件后,通过ls -al 命令可以查看该文件的文件类型,即第一个字符
Linux文件类型
Linux的文件类型有:套接字(s)、普通文件(-)、目录文件(d)、符号链接(b、c)、设备文件、FIFO(p)
Linux文件系统
文件系统概览
- FAT(File Allocation Table):例如FAT16、FAT32等,微软Dos/Windows使用的文件系统,使用一张表保存盘块的消息
- NTFS(New Technology File System):WindowsNT环境文件系统,NTFS对FAT进行了改进,取代了旧的文件系统
- EXT(Extended file System):扩展文件系统,这个是Linux的文件系统,EXT2/3/4数字表示第几代。
- Boot Selector:启动扇区,安装开机管理程序
- Block Group:块组,存储数据的实际位置
EXT文件系统
Inode Table是存放文件Inode的地方,每一个文件(目录)都有一个Inode,是每一个文件(目录)的索引节点。文件名不是存放在Inode节点上的,而是存放在目录的Inode节点上,列出目录文件的时候无需加载文件的Inode。Inode bitmap即Inode的位示图,记录已分配的Inode和未分配的Inode。Data block是存放文件内容的地方,每个block都有唯一的编号,文件的block记录在文件的Inode上。Block bitmap功能与Inode bitmap类似,记录Data block的使用情况。superblock是记录整个文件系统相关信息的地方,包括block和Inode的使用情况,以及时间、控制信息等。
命令 df -T:查看该系统所挂载的磁盘信息,查看文件系统的Inode信息:dumpe2fs 指定某个一设备,如 dumpe2fs /dev/sda2,使用超级管理员权限查看:sudo dumpe2fs /dev/sda2,查看文件的具体信息:stat dumpe2fs.log,文件重命名: mv dumpe2fs.log dumpe2fs.bak.log。Inode编号才是文件的唯一标记,文件名不是文件的唯一标记。
操作系统的设备管理
广义的IO设备
对CPU而言,凡是对CPU进行数据输入的都是输入设备;对CPU而言,凡是CPU进行数据输出的都是输出设备
- 按使用特性分类
- 存储设备:U盘、内存、磁盘等
- 交互IO设备:键盘、显示器、鼠标等
- 按信息交换的单位分类
- 块设备:磁盘、SD卡
- 字符设备:打印机、Shell终端
- 按设备的共享属性分类:独占设备、共享设备、虚拟设备
- 按传输速率分类:底速设备、中速设备、高速设备
IO设备的缓冲区
由于CPU与IO设备的速率不匹配,所以需要IO设备缓冲区,这样可以减少CPU处理IO请求的频率,提高CPU与IO设备之间的并行性。专用缓冲区只适用于特定的IO进程,当这样的IO进程比较多时,对内存的消耗也很大,操作系统划出可供多个进程使用的公共缓冲区,称之为缓冲池。
SPOOLing技术
SPOOLing技术是关于慢速字符设备如何与计算机主机交换信息的一种技术,利用高速共享设备将低速的独享设备模拟为高速的共享设备。逻辑上,系统为每一个用户都分配了一台独立的高速共享设备。SPOOling技术把同步调用低速设备改为异步调用。SPOOLing技术在输入、输出之间增加了排队转储环节(输入井、输出井),SPOOLing技术负责输入(出)井与低速设备之间的调度,逻辑上,进程直接与高速设备交互,减少了进程的等待时间。