赞
踩
计算机由外到内:
多个用户
各个软件
操作系统
硬件
操作系统目标:
方便(对用户)
有效(能运行用户的程序;高效,对系统)
可扩充
开放性
现代OS主要目标:
提高资源利用率
方便用户
操作系统作用:
是接口,是用户和计算机硬件系统之间的接口
实现了计算机资源的抽象
管理者,是计算机资源的管理者
组织者,是计算机工作流程的组织者(为众多作业切换处理机,协调它们的推进进度,提升系统性能)
发展历史:
https://www.bilibili.com/video/BV1Zc411D7sG
操作系统发展过程:
无操作系统的计算机系统
单道批处理系统
多道批处理系统
分时系统
实时系统
微机操作系统
无操作系统的计算机系统:
1 人工操作,穿孔纸带
2 脱机输入/输出方式,低速输入设备、磁带
单道批处理系统:
内存仅放置一个作业(= 程序)
,处理顺序尽可能提高资源利用率
缺点:
内存仅放置一个作业,造成内存浪费
CPU利用率不高,因为内存程序在完成I/O
后,CPU才能运行
多道批处理系统
1 多道程序设计技术
内存同时放置多个作业,这些作业宏观同时运行,微观交替执行,它们共享系统资源
2 多道批处理系统:多道程序设计技术的批处理系统
多道批好处(单道批、多道批):
1 提高CPU、内存、I/O
利用率
2 提高系统吞吐量
批处理好处:
资源利用率高
系统吞吐量大
分时系统的引入:
批处理系统(单、多)缺点:
无法进行人机交互
多用户无法同时使用计算机资源(它很宝贵的!)
因此引入分时系统
分时系统定义:
一个主机连接多个屏幕、键盘等终端(1960,最多连接30台终端机)
且允许多个用户同时用自己的终端和主机交互,即共享主机资源
分时系统目标:及时响应用户终端命令
分时系统实现细节:
时间片轮转运行的分时技术,把处理机的时间分成小时间片,轮流给各个终端使用,
分时系统特征:
多路 多个用户
独立 多个用户互不影响
及时
交互
实时系统:
系统及时响应外部事件请求,规定时间内完成事件处理
应用于:
工业武器控制
信息查询
多媒体系统(集电话、电视、媒体、计算机网络 于一身的信息综合化系统)
嵌入式系统(由硬件、软件组成,能独立进行运作的器件
)
实时系统:
多路、独立、及时、可靠、交互
分时系统和实时系统 区别在于及时性
、可靠
、交互性
:
及时性:
分时系统:用户能接受的响应时间
实时系统:秒级、毫秒级
可靠:
分时系统可靠
实时系统更可靠
交互性:
分时系统 交互性较好
实时系统 交互性较差
无结构 = 整体式:调试、维护不方便,可读、可扩充性较差
模块化结构OS:模块划分、接口的规定 困难,模块间存在依赖,使得机构不清晰
分层式结构OS
微内核结构OS
模块化 分层式
同:操作系统分为简单、独立的模块,它们可以交互,之间有接口
异:
分层式:
内部各个模块有序,不同层次的模块不能随意依赖、调用,只能单向依赖、单向调用
组织结构、依赖关系更清晰
系统可读性、可靠性、适应性增强
内核:是软件,是硬件的第一层软件扩充,常驻内存
目的:为减少系统开销,
包含:
与硬件紧密相关的(中断处理程序、设备驱动程序)、
基本的、公共的、
运行频率高的模块(如时钟管理、进程调度等)、
关键性数据结构
内核:单内核、微内核
单内核:是进程,其内部又有若干模块
用原语来实现 进程管理、文件系统、存储管理
微内核:
目标:将系统服务的实现 与 系统的操作规则分离
用原语来实现线程管理、地址空间、进程间通信
处理机执行状态:
系统态、用户态
系统态 = 核心态 = 内核态 = 管态:
权限高,访问、执行一切指令和区域
用户态 = 目态:
权限低,访问、执行部分指令和区域
基本特征:
并发、异步、共享、虚拟
并发最重要!
并发:多事件同一时间 间隔发生
多道程序环境下,多时间宏观同时进行,微观交替进行
程序:静态实体,不能并发,并发需要进程
进程:是活动实体,是系统中 能独立运行、能独立分配资源 的基本单位
进程的组成:机器指令、数据、堆栈、进程控制块
并行:多事件同时发生
并行包含并发
异步:
多道程序环境,每个程序何时执行、暂停 均未知,但结果可再现
共享:
系统的资源给多个并发的进程使用
共享:互斥共享、同时访问
互斥共享:资源当下仅被一个进程使用(打印机、变量、队列)
同时访问:资源当下被多个进程使用(磁盘、可重入代码)
虚拟:
物理实体变为逻辑上的对应物
使进程可以更方便共享系统资源
4个管理:
处理机、存储器、设备、文件
提供友好的用户接口
处理机分配、运行
处理机基本单位:进程
处理机管理 = 进程管理,包括:
进程的控制、同步、通信、调度
进程控制:为作业创建进程、撤销进程,控制进程的状态
进程同步:协调进程执行次序,使并发执行的程序 执行结果可再现
进程通信:进程之间的信息交换
进程调度:为多个就绪的进程分配处理机,得到处理机的就绪进程
投入执行
处理机 CPU 处理器
处理机:是部件,它处理计算机系统中存储程序和数据,使其按程序规定的步骤执行指令
cpu处理器:计算机系统的运算和控制核心,是信息处理、程序运行的最终执行单元
为多道程序运行提供好的环境
包括:内存分配、保护、扩充,地址映射
内存保护:
每个用户程序只在自己的内存空间中运行,各个程序互不影响
内存扩充:
逻辑上扩充内存容量,物理实际并没有,以便大作业的运行、增加可并发作业的数量
地址映射:程序的逻辑地址
转为内存的物理地址
完成用户I/O
请求,包括:
缓冲管理
设备分配
设备处理
缓冲管理:
缓冲CPU的高速与I/O
的低速
设备分配:
为用户分配设备、设备控制器,以便完成用户的I/O
请求
有通道的系统中,还为用户分配通道
设备处理:
启动设备I/O
操作,响应处理设备控制器发来的中断请求
使用户方便安全使用信息资源,包括:
管理 目录
管理 文件存储空间
文件共享
文件读写管理保护
用户接口、程序接口
用户接口:
联机用户接口:用户用联机命令直接控制自己作业
脱机用户接口:用户用作业控制语言间接控制自己作业
图形用户接口:用户可以用鼠标键盘操作
进程的控制、同步、通信、调度
进程基本状态(线程也是):
就绪:就差CPU了
执行:就绪 + CPU = 开始执行
阻塞:正在执行,因某事件而暂停
进程挂起、激活:
挂起的进程就不能竞争CPU了,它们处于静止状态
就绪、阻塞的进程才能挂起,对应 静止就绪、静止阻塞
激活:挂起的进程可以竞争CPU了
用于:
要准备足够的内存空间给就绪进程
调节系统负荷
检查资源使用情况
原语:
由若干指令组成的程序段,它实现某个特定功能,执行过程中不可中断
进程控制:创建撤销、阻塞唤醒、挂起激活
每个操作都用原语执行:
创建原语 撤销原语、
阻塞原语 唤醒原语、
挂起原语 激活原语
进程创建:新建PCB
申请空白PCB,分配资源,初始化PCB,尝试新进程插入就绪队列
Process Control Block
进程撤销(=终止)
:回收PCB
出现情况:
该进程执行完毕
异常错误
父进程请求
唤醒就是转为就绪
OS 基本特征:
并发、异步、共享、虚拟
中断引入目的:
多道程序设计、并发的必要条件:中断
必要条件:
多道程序设计、并发 → 中断
多道程序设计、并发 一定要有 中断
有 中断 不一定有 多道程序设计、并发
中断定义:
CPU运行一个进程a好好的,此时系统内外发生异步事件,CPU暂停该进程,去处理异步对应进程b,结束了再运行原进程a
异步:多道程序环境,每个程序何时执行、暂停 均未知,但结果可再现
中断源:引起中断的事件
进程同步:协调进程执行次序,使并发执行的程序 执行结果可再现
同步 互斥:
同步:
不同任务的若干程序片断,运行按某种先后次序 (次序依赖于要完成的特定的任务)
场景:两个及以上的进程线程在运行过程中协同步调,按预定次序运行。如 A 任务的运行依赖于 B 任务产生的数据。
互斥:
不同任务的若干程序片断,当运行其中一程序片段时,其它任务就不能运行
场景:一个公共资源同一时刻仅被一个进程、线程使用
临界资源(互斥):
一次只能被一个进程使用
临界区:访问临界资源的代码
异步:多道程序环境,每个程序何时执行、暂停 均未知,但结果可再现
同步:间接制约、直接制约
间接制约:出现在资源共享,如两个进程竞争一个打印机
直接制约:进程a需要进程b的结果才能继续执行
同步的规则:
空闲让进
忙则等待
有限等待:不死等
让权等待 :进程不能访问自己的临界资源时,释放处理机
进程同步的应用 - 信号量:
整型信号量、记录型信号量、AND型信号量
PV原子操作:
不会被线程调度机制打断;一旦开始,就一直运行到结束
wait(S)、signal(S)、P(S)、V(S)
------------------
wait(S) = P(S)
signal(S) = V(S)
整型信号量:
整型量S:仅有两个标准原子操作 wait(S)、signal(S)
未遵循让权等待,而是使进程处于忙等状态
wait(S):
while(S<=0)
{do nothing; 忙等,直到s>0停止}
S:=S-1;
------------------
signal(S):
S:=S+1;
记录型信号量:
在整数型信号量基础上改进 遵循让权等待
其数据结构:
typedef struct{
int value; 资源数目
list_of_process *L; 链接所有等待进程
}semaphore;
其PV操作:
void P(static semaphore *S) 申请资源 { S->value--; 资源用掉1个就减少1个 if(S->value < 0) { blocked(S->L); 加入阻塞队列 } } void V(static semaphore *S) 释放资源 { S->value++; if(S->value <= 0) { wakeup(S->L); 阻塞队列唤醒一个 } }
value初始为1时,此时是互斥的信号量
AND型信号量:
使用情景:多进程竞争多个临界资源,出现死锁的概率很大
思想:请求的资源全部分配给进程,要么一个也不分配
这里没有用到记录型信号量的数据结构
void P(S1,S2,...,Sn) 申请资源 { if(S1>=1 and S2>=1 and. .. and Sn>=1 ) { for(int i = 0; i < n ;i++) Si--; } } void V(S1,S2,...,Sn) 释放资源 { for(int i = 0; i < n ;i++) { Si++; 将与Si关联的队列中等待的所有进程移除到就绪队列中 } }
产生原因:
竞争资源
推进顺序非法
产生死锁必要条件:
互斥
请求和保持
不剥夺
环路等待
1 预防 2 避免
1 预防死锁:
破坏必要条件即可,互斥是设备固有属性,无法破坏
破坏 请求和保持
一次性获取资源,用完就释放
破坏 不剥夺
无法运行时释放已得资源
缺点:
不易实现
反复申请资源,增加系统负担,降低吞吐量
破坏 环路等待
资源编号,按编号递增获取资源
缺点:
增加系统负担
编号和系统规定顺序不同,造成资源浪费
2 避免死锁:
安全状态
若干进程按某顺序给资源,所以进程可以顺利完成
不安全状态
若干进程按该某顺序给资源,所以进程可以顺利完成,该顺序不存在
安全状态:
存在进程的安全序列P1,…,Pn,则系统处于安全状态。安全状态一定没有死锁发生
不安全状态:
不存在这样的进程安全序列
银行家算法
available 记录各资源可用情况
max 记录各进程对资源的需求
allocation 记录各进程已占有资源情况
need 记录各进程还需多少资源情况
request 记录某进程请求资源情况
易知:
need = max - allocation
银行家算法过程:
request > need,系统拒绝分配,error
else
request > available,资源无法满足请求,阻塞
else
{
available = available - request
allocation = allocation + request
need = need - request
}
执行安全性算法进行检测,若安全则继续下一步执行,否则,恢复上一步状态
安全性算法:
2个向量
work = available,资源可用情况
finish = false 记录系统是否可以满足进程资源需求
work = available,资源可用情况 finish = false 记录系统是否可以满足进程资源需求,先默认不能满足 while(1) { 找到进程i,有(finish[i] == flase && need[i] < work[i]) { work[i] += allocation[i] finish[i] = true } 找不到符合条件的进程 break } finish均true 序列安全 else 序列不安全
生产者消费者、哲学家进餐、读者写者问题
生产者消费者问题:
缓冲区大小n,生产者向其投入+1
,消费者拿取-1
需要3个信号量:
互斥信号量 mutex = 1,生产者 消费者互斥访问缓冲区
资源信号量 empty = n,空闲缓冲区数量
资源信号量 full = 0,满缓冲区数量
缓冲区全空,消费者等待
缓冲区全满,生产者等待
记录型信号量 PV操作:
typedef struct{
int value; 资源数目
list_of_process *L; 链接所有等待进程
}semaphore;
int in = 0, out = 0;
item buffer[n]; 缓冲区,n已知
semaphore mutex = 1, empty = n, full = 0; 信号量
生产者先空后满(缓冲区)
消费者先满后空
void proceducer() { where(true) { 生产nextp。。。 P(empty); 空缓冲区数量-1 P(mutex); 上锁,此时消费者不能获取缓冲区资源 buffer[in] = nextp; 产品放入缓冲区 in = (in+1)%n; 指针in+1 V(mutex); 解锁,此时消费者可以获取缓冲区资源 V(full); 满缓冲区数量+1 } } void consumer() { where(true) { P(full); 满缓冲区数量-1 P(mutex); 上锁,此时生产者不能获取缓冲区资源 nextc = buffer[out]; 购买消费产品 out = (out + 1)%n; 指针out+1 V(mutex); 解锁,此时生产者可以获取缓冲区资源 V(empty); 空缓冲区数量+1 。。。 } } void main() { proceducer();proceducer(); consumer();proceducer();。。。 }
ADN型信号量:
typedef struct{
int value; 资源数目
list_of_process *L; 链接所有等待进程
}semaphore;
int in = 0, out = 0;
item buffer[n]; 缓冲区,n已知
semaphore mutex = 1, empty = n, full = 0; 信号量
void proceducer() { where(true) { 生产nextp。。。 P(empty, mutex); 空缓冲区数量-1; 上锁,此时消费者不能获取缓冲区资源 buffer[in] = nextp; 产品放入缓冲区 in = (in+1)%n; 指针in+1 V(mutex, full); 解锁,此时消费者可以获取缓冲区资源; 满缓冲区数量+1 } } void consumer() { where(true) { P(full, mutex); 满缓冲区数量-1; 上锁,此时生产者不能获取缓冲区资源 nextc = buffer[out]; 购买消费产品 out = (out + 1)%n; 指针out+1 V(mutex, empty); 解锁,此时生产者可以获取缓冲区资源; 空缓冲区数量+1 。。。 } } void main() { proceducer();proceducer(); consumer();proceducer(); 。。。 }
哲学家进餐:
哲学家要么吃饭 要么思考,他们坐在1张桌子,5个碗,5只筷子
筷子是临界资源,相邻哲学界取筷子互斥
代码来源:
https://blog.csdn.net/Yun_Ge/article/details/89177918
若针对筷子进行 信号量进程同步:
typedef struct{ int value; 资源数目 list_of_process *L; 链接所有等待进程 }semaphore; semaphore chopstick[5] = {1,1,1,1,1}; while(true) { 哲学家吃饭,先拿左边的筷子,再拿右边的筷子 wait(chopstick[i]); wait(chopstick[(i+1)%5]); 吃饭... 哲学家吃完饭思考,先放下左边的筷子,再放下右边的筷子 signal(chopstick[i]); signal(chopstick[(i+1)%5]); }
可能会造成死锁:哲学家都在拿左筷子,都需要右筷子
解决办法:
1 仅允许4个哲学家同时进餐
2 哲学家进餐要全给两个筷子,要么一个也不给
3 奇数号哲学家先拿左筷子,偶数号哲学家先拿右筷子
仅允许4个哲学家同时进餐:
typedef struct{ int value; 资源数目 list_of_process *L; 链接所有等待进程 }semaphore; semaphore chopstick[5]={1,1,1,1,1}; semaphore count=4; // 设置一个count,最多有四个哲学家可以进来 void philosopher(int i) { while(true) { think(); P(count); 请求进入房间进餐 count=0时,不能允许哲学家再进来了 P(chopstick[i]); 请求左手边的筷子 P(chopstick[(i+1)%5]); 请求右手边的筷子 eat(); V(chopstick[i]); 释放左手边的筷子 V(chopstick[(i+1)%5]); 释放右手边的筷子 V(count); 离开饭桌释放信号量 } }
哲学家进餐要全给两个筷子,要么一个也不给
这个过程中可能只能有1人在吃饭,效率低,有5只筷子,其实是可以有2人同时吃饭
semaphore mutex = 1; 判断两根筷子是否可用,并保护起来 semaphore chopstick[5]={1,1,1,1,1}; void philosopher(int i) { while(true) { think(); P(mutex); 保护信号量 P(chopstick[(i+1)%5]); 请求右手边的筷子 P(chopstick[i]); 请求左手边的筷子 V(mutex); 释放保护信号量 eat(); V(chopstick[(i+1)%5]); 释放右手边的筷子 V(chopstick[i]); 释放左手边的筷子 } }
ADN型信号量:
semaphore chopstick[5]={1,1,1,1,1};
while(true)
{
think();
P(chopstick[(i+1)%5],chopstick[i]);
eat();
V(chopstick[(i+1)%5],chopstick[i]);
}
奇数号哲学家先拿左筷子,偶数号哲学家先拿右筷子
semaphore chopstick[5]={1,1,1,1,1}; void philosopher(int i) { while(true) { think(); if(i%2 == 0) //偶数哲学家,先右后左。 { wait (chopstick[(i + 1)%5]) ; wait (chopstick[i]) ; eat(); signal (chopstick[(i + 1)%5]) ; signal (chopstick[i]) ; } else //奇数哲学家,先左后右。 { wait (chopstick[i]) ; wait (chopstick[(i + 1)%5]) ; eat(); signal (chopstick[i]) ; signal (chopstick[(i + 1)%5]) ; } } }
读者写者问题:
读文件进程 - “Reader进程”,其它进程 - “Writer进程”
读可以共享,写只能独享
记录型信号量:
3个信号量
wmutex = 1 写程序独享临界资源
rmutex = 1 因为文件是临界资源,需要互斥访问
rcount = 0 读进程共享临界资源,对访问该临界资源的读进程计数
typedef struct{ int value; 资源数目 list_of_process *L; 链接所有等待进程 }semaphore; semaphore wmutex = 1; semaphore rmutex = 1; int rcount = 0;// 记录有几个读者 void reader() 读进程 { while(true) { P(rmutex); rmutex保护rcount计数 if(rcount == 0) { P(wmutex); 第一个读进程进入,封锁写进程 } rcount++; 计数 V(rmutex); 读文件。。。 P(rmutex); rcount--; if(rcount == 0) { V(wmutex); 保证最后一个读进程读完,释放读程序 } V(rmutex); } } void writer() { while(true) { P(wmutex); 写文件。。。 V(wmutex); } }
进程通信:进程之间的消息交换,也用原语
低级通信:交换信息量少,效率低,对用户不可见
进程通信类型(高级通信):
共享存储器系统:
消息传递系统
管道通信
客户机服务器系统
还有直接通信:消息缓冲队列通信
共享存储器系统:
共享存储区的读写 做消息缓冲区,高级通信
若用数据结构做缓冲区,低级通信
消息传递系统:
格式化消息为单位, = 网络中报文
直接通信 间接通信
直接通信:直接发消息给对方
两个原语:send(接收者, 格式化消息)
、receive(发送者, 格式化消息)
间接通信:信箱读写 做消息缓冲区
可实现实时通信、非实时通信
管道通信:
管道:两进程共享一个文件,这个文件消息读写 做消息缓冲区
客户机服务器系统 3种:
套接字
远程过程调用
远程方法调用
套接字:
类似管道通信
文件做消息缓冲区,文件类型的套接字关联这个共享文件,两进程还在一个计算机上
网络类型的套接字:
通信的目的地址
端口号
通信网络的传输层协议
进程所在的网络地址
两进程(接收、发送进程)各有一个套接字
远程过程、远程方法:
会用到:RPC(Remote Procedure Call) 通信协议
消息缓冲队列:
发送进程将消息写在消息缓冲区
,消息缓冲区放在消息缓冲队列中
接收进程在消息缓冲队列取下一个消息缓冲区
其 消息缓冲区 数据结构:
struct message_buffer
{
int sender; 发送者进程标识符
int size; 消息长度
char *text; 消息正文
struct message_buffer *next; 链表指针
}
其PCB增加:
mq 消息缓冲队列 首指针
sm 消息缓冲队列 资源信号量
mutex 消息缓冲队列 互斥信号量
发送、接收原语:
发送原语:
void send(receiver, message_buffer a) receiver:接收进程标识符, a:发送区地址 = 内存空间
{
getbuf(a.size, b); 根据a.size申请 消息缓冲区b
b.sender= a.sender;
b.size = a.size;
copy(b.text, a.text);
b.next = 0;
getId(PCBset, receiver, j); 获取 接收进程控制块j
P(j.mutex);
insert(&j.mq, b); 消息缓冲区b 插入 消息队列j中
V(j.mutex);
V(j.sm);
}
接收原语:
void receive(message_buffer b) b:接收区地址 = 内存空间
{
j = internal_name; 获取接收进程的PCB
P(j.sm);
P(j.mutex);
remove(j.mq, a); 消息队列第一个消息j 移出至 消息缓冲区a
V(j.mutex);
b.sender= a.sender;
b.size = a.size;
copy(b.text, a.text);
b.next = 0;
releasebuf(a); 释放 消息缓冲区a
}
处理机调度引入的目的:
多道程序环境下,内存中的进程数量 > 处理机数量(CPU),需要某种算法把CPU分配给就绪的进程
处理机调度的目标:
资源利用率高且平衡利用,系统吞吐量大,公平对待不同类型的作业
三级调度:
高级调度、低级调度、中级调度
作业调度 进程调度 处理机调度
高级调度 = 作业调度(外存→内存):
把外存中 后备队列的作业 选择性的调入内存(就绪队列)
低级调度 = 进程调度 = 处理机调度(内存→CPU):
就绪队列中的进程选择性的给予处理机(CPU)
两个方式:
剥夺式 = 抢占式
非剥夺式 = 非抢占式
剥夺式 = 抢占式:
根据进程优先级,把当前正在运行的程序转入就绪,来运行另一个进程
原则:
优先级、短作业优先、时间片原则
非剥夺式 = 非抢占式:
不主动把当前正在运行的程序转入就绪,除非它自己已经完成或因某时间而转入阻塞
不能满足紧急任务
中级调度 = 对换功能(外存→内存):
暂时不能运行的程序放入外存去 等待(=挂起)
,而不是内存的就绪队列中
存在于分时系统、有虚拟存储器的系统
运行频率
低级 > 中级 > 高级
先来先服务 FCFS
短作业优先 = 最短剩余时间优先 SJF
时间片轮转 RR
优先级 HPF
高响应比优先 HRP
多级反馈队列 FB
先来先服务 FCFS,非抢占:
first come first service
优点:公平,容易实现
缺点:不利于短作业和I/O
作业
短作业优先 SJF,非抢占:
Shortest Job First
优点:容易实现
缺点:效率不高,忽视了作业等待时间,会出现饥饿现象(= 大作业等待时间过长)
优先级调度算法 HPF:
high priority first
优先级设置:
静态优先、动态优先
静态优先:进程创建时,其优先权就已确定,不再变化
动态优先:进程创建时,其优先权就已确定,但会变化
高响应比优先 HRP HRRN 抢占式:
Highest Response Ratio Next
响应比 =
响应时间
=
等待时间
+
要求服务时间
要求服务时间
\frac{响应时间 = 等待时间 + 要求服务时间}{要求服务时间}
要求服务时间响应时间=等待时间+要求服务时间 =
等待时间
要求服务时间
\frac{等待时间}{要求服务时间}
要求服务时间等待时间 + 1
等待时间越长,响应比越大
要求服务时间越短,响应比越大
服务时间:使用CPU的时间
优点:
短作业、先后次序兼顾,长作业不会长期得不到服务
缺点:
增加系统开销
多级反馈队列 FB 抢占式:
Multilevel Feedback Queue Scheduling
不同队列,其优先级不同
优先级越高,时间片越短
插入队列按照 先来先服务 FCFS顺序
若时间片内未完成就插入下一级队列末尾,再下一级…
该系统需要有快速切换机制
2个调度算法
最早截止时间优先 EDF
最低松弛度优先 LLF
最早截止时间优先 EDF
Earliest Dealine First
非抢占
截止时间越早,优先级越高
最低松弛度优先 LLF
Least Laxity First
松弛度越低,优先级越高
松弛度=截止时间-服务时间-当前时间
服务时间=调用CPU的时间=本身运行的时间
周转时间
响应时间
截止时间
周转时间:
外存后备队列等待时间
内存就绪队列等待时间
CPU上执行时间
等待I/O
操作时间
单个作业周转时间:
T
i
T_i
Ti = 完成时刻
−
-
− 提交时刻
n
n
n个作业平均周转时间:
T
=
1
n
∑
i
=
1
n
T
i
T = \frac{1}{n} \sum_{i=1}^n {T_i}
T=n1i=1∑nTi
单个作业 带权周转时间:
W
i
W_i
Wi =
周转时间
服务时间
\frac{周转时间}{服务时间}
服务时间周转时间
服务时间:使用CPU的时间
n
n
n个作业 带权平均周转时间:
W
=
1
n
∑
i
=
1
n
W
i
W = \frac{1}{n} \sum_{i=1}^n {W_i}
W=n1i=1∑nWi
响应时间:
响应时刻
−
-
−键盘输入时刻
截止时间:
开始截止时间、完成截止时间
程序顺序执行特征:
顺序
封闭
可再现性
独享资源
并发:同一时间间隔内交替执行
程序并发执行特征 = 程序不能并发执行的原因
:
间断:执行 间断 执行
不封闭:一个程序会受其他程序影响
结果不可再现:一个程序重复执行,结果不同
共享资源
进程引入的目的:
内存中的多道程序能正确的并发执行
提高资源利用率、提高系统的效率
线程引入目的:
减少程序并发而付出的时空开销
并发程度更好
没有进程的程序不能并发执行的原因 = 程序并发执行特征
进程的几个定义:(进程 程序)
1 是程序的一次执行
2 是程序、其数据在处理机上顺序执行所发生的活动
是程序在一个数据集合上运行的过程
是进程实体的运行过程
3 是CPU调度的 分配单位
线程定义:
进程内的执行单位 = 进程内可调度法实体
是CPU调度 的执行单位
线程包含线程
进程的组成:
机器指令、数据、堆栈、进程控制块PCB
线程组成:
线程标识符、程序计数器、寄存器、堆栈
线程3个基本状态:
就绪:就差CPU了
执行:就绪 + CPU = 开始执行
阻塞:正在执行,因某事件而暂停
进程特征:
并发:多个进程一段时间同时执行
异步:多道程序环境,每个程序何时执行、暂停 均未知,但结果可再现
动态:程序执行过程动态
独立:各个实体独立的 运行、分配资源、接受调度
OS 基本特征:
并发、异步、共享、虚拟
处理机执行状态:
系统态、用户态;
系统态 = 核心态 = 内核态 = 管态:
权限高,访问、执行一切指令和区域;
用户态 = 目态:
权限低,访问、执行部分指令和区域
线程:
用户级线程、内核支持线程
用户级线程:
线程仅在用户级中,线程的 创建 撤销 切换 不通过OS内核执行
切换速度块
内核支持线程:
线程在内核中,线程的 创建 撤销 切换 通过OS内核执行
内核级 相对 用户级线程 的优势:
同一进程的多个线程可以在多个处理器中
一个线程被阻塞,内核可以调度同一进程的其他线程
内核本身也可以用多线程实现
缺点:
速度、效率不如用户级
其原因是:
即使CPU在同一进程多个线程之间切换,也要陷入内核
陷入内核:
管程引入目的:
信号量机制的缺点:
进程自备同步操作,P(S)和V(S)操作大量分散在各进程中,不易管理,容易死锁
定义:
是软件模块:包含 局部于自己的公共变量 + 所有访问公共变量的过程所
管程组成:
1 局部于管程的共享变量
2 对数据结构进行操作的过程
3 对局部于管程的数据进行初始化的语句
管程的属性:
共享、互斥
安全
封装
共享、互斥:
管程可被进程互斥访问,属于共享资源
安全:
管程局部变量只能被管程的过程访问,不允许进程、其它管程直接访问
管程不能访问不属于它的变量
封装:
管程内的数据结构是私有的,只能在管程内使用,管程内的过程也只能使用管程内的数据结构。
进程通过调用管程的过程使用临界资源
进一步提高系统并发数量,对线程进一步分割,这就是协程
进程控制块PCB(Processing Control Block)
PCB记录了信息,这些信息有:
进程标识符
处理机状态
进程调度、控制信息
它们是OS所需要的、用于描述进程的当前情况
PCB的引入:描述、控制 进程的运行
PCB作用:将程序变成可以并发执行的进程
系统通过PCB感知、控制进程,PCB是进程的唯一标志
多个PCB组织方式:线性、链接、索引
c、c++程序设计步骤:
编辑,预编译,编译,链接,调试运行
名空间 地址空间 主存的存储空间
名空间=名字空间:
符号名的集合
符号指令、地址空间、I/O说明
高级语言的源程序存储在名空间中
存储器包括
CPU寄存器
内存=内存储器=主存=主存储器
辅存
精细一点:
CPU寄存器
高速缓存 Cache
内存=内存储器=主存=主存储器
辅存
可移动介质
(由上往下:
速度越来越慢,
价格越来越低,
容量越来越大)
CPU寄存器:
放程序指令、运算数据
高速缓存 Cache :
引入目的:缓解Cache与主存储器速度不匹配
内存=内存储器=主存=主存储器:
CPU可直接访问内存
分类:
只读存储器 ROM (Read-Only Memory
)
随机存取存储器(读写) RAM(Random Access Memory
)
外存=外存储器=辅存=辅助存储器:
有磁带、磁盘
CPU不能直接访问
其基本单位:块=物理块
对应文件管理
内存管理 磁盘存储管理
为多道程序运行提供好的环境
包括:内存分配、保护、扩充,地址映射
内存保护:
每个用户程序只在自己的内存空间中运行,各个程序互不影响
内存扩充:
逻辑上扩充内存容量,物理实际并没有,以便大作业的运行、增加可并发作业的数量
地址映射:
程序的逻辑地址
转为内存的物理地址
(地址重定位)
内存组成:
存储信息的物理单元(字、字节)
每个单元(内存单元
)都有地址
内存地址=地址:
内存单元的编号
虚拟地址=逻辑地址:
源代码编译,链接后生成可执行目标程序,在目标程序中每个变量指令对应唯一编号该编号就是虚拟地址
内存单元:
字
存储单元:存放一个机器字,字地址
字节
存储单元:存放一个字节,字节地址
存储空间=绝对地址空间:
内存单元的集合
物理地址 = 绝对地址 :
内存单元的实际地址(在内存里)
地址空间=物理地址空间:
物理地址的范围
虚拟地址空间:
同一程序虚拟地址的集合
作业虚拟地址空间:
作业中各程序虚拟地址空间的并集
(作业、程序、进程)
程序在外存中存储,将其装入内存的过程
程序转入方式:
绝对装入方式
静态重定位
动态重定位
绝对装入方式:
程序被装入内存,其逻辑地址=实际内存地址,无须对程序和数据的地址进行重定位。
程序被装入内存,其逻辑地址(虚拟地址)
≠实际内存地址(物理地址)
重定位:
虚拟地址转为物理地址的过程
静态重定位:
程序被装入时,虚拟地址转为物理地址,以后无需转换
缺点:不便于维护,影响存储空间利用率
实例:DOS操作系统
动态重定位:
程序被装入时,未进行地址转换,有需要时再转换
存储管理单元MMU
:
memory management unit
动态重定位的控制逻辑
程序链接:
静态链接、
装入时动态链接
运行时动态链接
静态链接:
程序运行前(装入前),目标模块和所需库函数链接为一个完整模块
装入时动态链接:
程序运装入前时,目标模块转入时,需要外部模块,就去找该外部模块,装入内存
运行时动态链接:
程序运运行时,需要外部模块未在内存,就去找该外部模块,装入内存
常规存储管理办法、虚拟存储器
分区
分页
分段
段页式
分区:针对内存,划分大小给作业使用
分页:针对作业,划分为大小相同的模块,有效利用内存
分段:针对作业,划分为大小可以不同的模块,满足用户
段页式:针对作业,划分为大小可以不同的模块,满足用户,对每个模块划分大小相同的子模块
常规存储管理的特征:
一次性、驻留性
一次性:作业一次性放进内存,才能运行
驻留性:作业放进内存后,直到运行结束,才能移出内存
存储单元连续
单一连续分配
固定分区分配
可变分区分配=动态分区分配
伙伴系统
单一连续分配:
有系统区、用户区
系统区:供OS用
用户区:放作业
实例:单用户操作系统,MS-DOS
固定分区分配:
内存有若干分区,这些分区大小不可改变,每个分区可转入一个作业,多道程序可用
内部碎片:作业大小与分区大小不相等
用静态重定位
存储保护:
限界寄存器,进程运行时,基址寄存器放分区地址(首地址),限界寄存器放分区最后一个存储单元地址
可变分区分配 = 动态分区分配:
引入目的:克服固定分区分配的缺点(碎片)
作业转入,在可用内存动态分配大小与作业相等的分区
分区分配算法:
首次适应
循环首次适应
最佳适应
最坏适应
首次适应:从头找大小合适的分区
循环首次适应:
从上次分区后面找大小合适的分区
回收处理:
4种情况,下图R是回收的:
用动态重定位
存储保护:
限界寄存器,进程运行时,基址寄存器放分区地址(首地址),限界寄存器放分区最后一个存储单元地址
缺点:
动态算法复杂
存在碎片,回收空闲分区要分区合并,系统开销大
伙伴系统
每次对一个作业要装入内存,若作业大小要小于可用内存的一半,内存大小分为两半,一个给作业
对换、覆盖
对换、覆盖可对内存进行逻辑扩充
对换:
内存种暂时不能运行的进程、程序、数据转到外存中
整体对换=进程对换:
以整个进程为单位
页面对换=分段对换=部分对换:
以 页 段 为单位
覆盖:
小内存运行大作业不再是空想
将程序分成几个功能独立的程序段,根据程序的逻辑结构,不能同时执行的程序段共享相同的内存区域
对换与覆盖异同点:
结构不同
对换:不要求程序员给出程序段之间的交换通道结构
覆盖:要求程序员在程序段之间提供覆盖结构
单位不同
对换的范围:进程或作业之间的交换
覆盖的范围:相同的过程中进行
效果不同
对换:单进程大小 < 内存实际大小
覆盖:单进程大小 > 内存实际大小 是允许的
页、页长、页号:
针对作业进行划分,每一部分大小相等(
2
k
2^k
2k字节),每一部分为页
,大小为页长
,每一页
有页号
0,1,2。。。
存储块、块号:
对内存划分,每一部分和页长
一样,每一部分是存储块
,每一部分有块号
0,1,2。。。
硬件:
页表机制、地址变换机构
页表:
作用:页号和块号一一对应的记录表
地址结构:
页长大小是
2
k
2^k
2k字节
逻辑地址长度 n 位
页号 = 页内偏移量
页长 = 最大偏移量
偏移量 = 位移量
地址变换:
虚拟地址转为物理地址
虚拟地址=逻辑地址:
源代码编译,链接后生成可执行目标程序,在目标程序中每个变量指令对应唯一编号该编号就是虚拟地址
物理地址 = 绝对地址 :
内存单元的实际地址(在内存里)
地址变换机构:
普通页表的缺点:
页表在内存中,访问数据有两步
1 访问页表,找到物理块号
,及对应偏移量
,形成物理地址
2 根据物理地址
访问数据(该数据也在内存中哦)
引入快表目的:
普通页表经过两步才能访问数据,效率低
块表经过一步才能访问数据!
快表:
地址变换机构中增加 可并行处理的高速缓冲寄存器
运算过程:
1 由逻辑地址
,得页号
,将页号
与快表中的页号
比较
2 有匹配的页号(命中),直接得对应的块号
, 再和页内偏移量
拼接形成物理地址
, 访问之。 一步即可访问数据
3 如果没有找到匹配的页号(未命中), 则访问内存中的页表两步访问。找到页表项后, 将其存入快表,若快表已满, 则按照某算法对旧的页表项进行替换
多级页表:
现代计算机,页表有时很大,有时没有那么大的连续空间
多级页表:对页表分页!
点我 请求分页存储管理方式
分页 page:
页、页长、页号:
针对作业进行划分,每一部分大小相等(
2
k
2^k
2k字节),每一部分为页
,大小为页长
,每一页
有页号
0,1,2。。。
引入分段的目的:
方便用户编程
有利于信息的共享保护
有利于段的动态增长、动态链接
分段:
逻辑段、段号、段长、基址:
针对作业进行划分,根据作业的逻辑关系,把作业划分成每个大小可以不相等的逻辑段(
2
k
2^k
2k字节)
每个逻辑段
对应一个过程、程序模块、数据集合
段号:每个逻辑段
的编号0,1,2。。。
段长:每个逻辑段
的容量大小
基址:每个逻辑段
在内存中的物理地址
段内地址连续
不同段的地址可以不连续
逻辑地址 = 段号 + 段内偏移地址
段表:
作用:段号、段长和基址一一对应的记录表
分页 分段 异同点:
页是物理单位
段是逻辑单位
分页:实现离散分配方式,消减内存的碎片,提高内存的利用率,不考虑用户
分段的目的:更好的满足用户的需要
页的大小固定,由系统确定
段的长度不固定,根据信息的性质来划分
分页的作业地址空间是一维
分段的作业地址空间是二维
先分段,后分页
段号、段内页号、页内偏移量:
虚拟存储器:针对内存不够用、小内存运行大作业
常规存储管理办法的特征:
一次性:作业一次性放进内存,才能运行
驻留性:作业放进内存后,直到运行结束,才能移出内存
虚拟存储器:
局部性原理:
1 存取指令、数据,所访问的存储单元都聚在较小的连续区域中
2 程序可以部分装入内存,就可以运行,运行结束,也不马上调出内存
虚拟存储器特征:
多次、对换、虚拟
多次性:作业分块多次调入内存
对换性:与驻留性
不同,对换性将内存暂时不用的程序、数据调出内存至对换区,提高内存利用率
虚拟性:小内存运行大作业的感觉
虚拟内存 = 虚存:逻辑上比实际内存大的内存, = 实际内存 + 部分磁盘
虚拟地址:虚拟内存中的指令和数据
虚拟地址空间:给进程的虚拟内存
虚拟存储器的基础:离散分配作业
硬件基础:
一定容量的内存、大外存
请求分页的页表机制、请求分段的段表机制
缺页中断机构、缺段中断机构
地址变换机构
虚拟存储器管理方式:
请求分页存储管理方式
请求分段存储管理方式
页、页长、页号:
针对作业进行划分,每一部分大小相等(
2
k
2^k
2k字节)
每一部分为页
,大小为页长
,每一页
有页号
0,1,2。。。
存储块、块号:
对内存划分,每一部分和页长
一样,每一部分是存储块
,每一部分有块号
0,1,2。。。
点我跳转分页
将作业的部分装入内存,作业就在运行,而不是全部装入内存
请求页表机制:
逻辑地址 转为 内存中的物理地址
请求分页中,内存分配、置换策略的组合:
内存分配:固定分配、可变分配
置换策略:全局置换、局部置换
固定分配无法全局置换,只能局部置换
3种组合:
固定分配 局部置换
可变分配 全局置换
可变分配 局部置换
调页策略:
请求调页、预调页
请求调页:
发现内存中需要的页不存在,就触发缺页中断
,将其调入内存
预调页:
在正常运行的时候,提前把部分页调入内存中,成功概率50%。。。
抖动:
频繁调动页面,说明选择的置换算法有问题!
置换算法:
请求调页,发现内存中需要的页不存在,就触发缺页中断
,将其调入内存,内存已满,此时需要选择内存已存在的页调出内存至外存
6个置换算法:
最佳置换(OPT)
先进先出置换(FIFO)
最近最久未使用(LRU)(重点)
时钟(CLOCK)置换
最少使用(LFU)
页面缓冲(PBA)
最佳置换(OPT):
Optimal Replacement Algorithm
理想法:
在内存中被调出页:以后不再用 或 最长时间没有调用的页面
难以实现
先进先出置换(FIFO)
First in, First out
在内存中被调出页:最先进入内存的页面
实现简单,性能差
最近最久未使用(LRU)
Least Recently Used
在内存中被调出页:最近一段时间最久未被用到的页面
性能较好
时钟(CLOCK)置换 接近 LRU
附加位 = 使用位
未被用到,使用位是0
,用了就是1
最少使用(LFU)
Least frequently used
在内存中被调出页:最近一段时间用的次数最少的页面
效果不佳,常用的页面可能此时没用,以后还要用,增加无益操作
页面缓冲(PBA)
Page Buffering Algorithm
在内存中被调出页:空闲页面缓冲池 = 空闲页链表
空闲块:淘汰页面占用的内存块
内存块要被淘汰了,不直接调出内存,而是挂到空闲页链表的尾部
若缺页了,先去空闲页面缓冲池找,找不到再去外存找,再在内存为其开辟空间
请求调段、段置换
我觉得磁盘也属于存储管理的一部分
磁盘调度所有书都是将其放在设备管理中,因为书上说存储器指的是主存(内存),但这样明显不符合逻辑。。。
书上称 外部设备是 除了中央处理器(CPU)、主存储器外的其他硬件,所以磁盘就是外部设备,也行吧。。。
磁盘空间管理 = 文件空间管理
点我 文件空间管理
磁盘调度:减少磁盘平均寻道时间,减少磁头移动总量
先来先服务 FCFS
(first come first service
)
最短时间寻道优先 SSTF
(Shortest Seek Time First
)
扫描法 SCAN
循环扫描法 CSCAN
(circulate scan
)
N-Step-SCAN 算法
扫描法 SCAN
:
沿着磁头移动方向,选择距其最近的请求,磁头到底,反方向移动
循环扫描法 CSCAN
(circulate scan
):
沿着磁头移动方向,选择距其最近的请求,磁头到底,从头开始移动,移动方向没变
N-Step-SCAN 算法:
磁盘请求队列分成n个子队列,按FCFS处理子队列。
每处理一个子队列时,按SCAN算法
I/O
系统:
数据输入、输出、存储
I/O
系统的 基本功能、设备类型、组成、控制方式
组成:I/O
软件层次结构、硬件
外部设备:除了中央处理器(CPU)、主存储器外的其他硬件
基本功能、设备类型、组成
I/O
系统基本功能:
1 隐藏物理设备细节
2 与设备的无关性:提高OS可移植性、适应性
3 提高处理机和I/O
的利用率
4 对I/O
设备进行控制
5 确保设备的正确共享
6 错误处理
I/O
设备类型分类:
从属关系:系统设备、用户设备
传输信息:字符设备、块设备
传输速率:低速、中速、高速设备
资源分配:独占、共享、虚拟设备
I/O
系统 结构:
总线型、通道型
I/O
接口 的功能、组成
I/O
接口 组成
I/O
软件 层次结构:
1 用户层I/O
软件:与用户交互的接口,用户通过 用户层I/O
软件 操作设备
2 设备独立性软件:程序与设备的接口、命名、保护、分配
3 设备驱动程序:数据传输
4 中断处理程序
I/O
系统 硬件:
I/O
设备:I/O
操作的机械部分
设备控制器 = 适配器:控制I/O
的电子部分,CPU与I/O
的硬件接口
控制方式、设备缓冲、设备分配、设备处理
I/O
系统的 控制方式:
程序控制I/O
(早期) = 忙-等
方式 = 循环检测I/O
中断方式
DMA方式
通道方式
中断方式:
程序控制I/O方式 = 程序直接控制外部设备传输 = “忙-等”方式 = 循环测试I/O
方式
CPU通过程序,直接在设备控制器中的 数据寄存器 存放数据,控制设备I/O
操作,在设备实施时,循环测试状态寄存器的忙闲标志位,判断设备操作是否完成
I/O控制器 = 设备控制器:
存在于在信息传输中,是OS和硬件设备之间的接口,接受CPU指令,控制I/O
操作
信息传送方式分类:
无条件传送方式
条件传送
无条件传送方式:
事先知道外部设备经过多久可以准备好发送、接收数据,超过这段时间,进行I/O
操作
条件传送=查询控制方式:
优点:
所需硬件少
缺点:
循环测试浪费时间,降低效率
中断 通道
引入中断目的 = 查询方式的缺点:
CPU对外部设备查询时,不能做别的事,效率低
外设所需服务时间的间隔 < CPU对多个外设轮询循环的时间,导致数据丢失
中断:
某事件使CPU暂停当前程序运行,CPU转入对改事件的处理
缺点:
需要响应的硬件
一次中断,需要保护恢复现场,发出多个指令,浪费CPU时间,只适用于少量数据和中低速设备
引入DMA目的:
内存和I/O
设备直接传送数据,不需要CPU干涉
一般数据传送,从外部设备传到内存的步骤:输入指令,将外设取入CPU内部的寄存器或累加器,再将其输出至指定单元
DMA
Direct Memory Access
DMA实现方式:
DMAC=DMA控制器
DMA优点:
数据传送速度、响应时间极大提高
DMA缺点:
I/O设备的管理、其它操作仍需CPU来完成,而不是DMAC
引入通道目的:
让CPU摆脱管理、控制 I/O
(输入输出)的沉重负担,这项工作由通道
来完成
完成用户I/O
请求,包括:
缓冲、分配、处理
缓冲管理:
缓冲CPU的高速与I/O
的低速
设备分配:
为用户分配设备、设备控制器,以便完成用户的I/O
请求
有通道的系统中,还为用户分配通道
设备处理:
启动设备I/O
操作,响应处理设备控制器发来的中断请求
设备处理 = 设备驱动,是设备控制的核心模块
其任务:
接受上层的凑向命令,如打开关闭文件,把命令转为具体要求命令
缓冲CPU的高速与I/O
的低速
单缓冲
双缓冲
循环缓冲
缓冲池
单缓冲
某一时刻只能输入或输出数据,不能并行,属于临界资源
双缓冲:
输入输出数据可以并行
循环缓冲:
主存(=内存)中分配大小相同的缓冲区,接口是循环链表
仅适用于:特定I/O、计算进程
是专用缓冲
缓冲池:
Buffer pool
其缓冲期可以让多个进程共享
可输入输出的缓冲池
其3类缓冲区:
空缓冲区
装满输入数据的缓冲区
装满输出数据的缓冲区
同一类型的缓冲区构成队列
空缓冲区队列 emq
输入队列 inq
输出队列 outq
头指针F(emq)
缓冲池的其它4个工作缓冲区:
收容输入数据 hin
提取输入数据 sin
收容输出数据 hout
提取输出数据 sout
工作方式的2个操作
Getbuf(type)
、Putbuf(type, number)
Getbuf(type)
:type所指定的队列的队首 取一个缓冲区
Putbuf(type, number)
:number指示的缓冲区挂在type队列上
MS(type) 队列互斥信号量 RS(type) 队列资源信号量 Takebuf(type) type所指定的队列的队首 取一个缓冲区 Addbuf(type,number) number指示的缓冲区挂在type队列上 void Getbuf(unsigned type){ P(RS(type)); P(MS(type)); B(number)=Takebuf(type); V(MS(type)); } void Putbuf(type,number){ P(MS(type)); Addbuf(type,number); V(MS(type)); V(RS(type)); }
工作方式:
收容输入 Getbuf(emq)
→ Putbuf(inq, hin)
提取输入 Getbuf(inq)
→ Putbuf(emq, sin)
收容输出 Getbuf(emq)
→ Putbuf(outq, hout)
提取输出 Getbuf(outq)
→ Putbuf(emq, sout)
空缓冲区队列 emq
输入队列 inq
输出队列 outq
数据结构
分配算法
SPOOLing系统
其数据结构:
设备控制表 DCT(Device Control Table
)
控制器控制表 COCT(Controler Control Table
)
通道控制表 CHCT(Channel Control Table
)
系统设备表 SDT(System Device Table
)
设备分配2类:
静态:系统一次性给作业分配所要求的全部设备、控制器、通道
动态:进程执行期间根据需求动态分配
设备分配算法:
先来先服务 FCFS first come first service
优先级 HPF high priority first
SPOOLing系统 = 假脱机技术 = 外部设备同时联机操作
Simultaneous Peripheral Operations On-Line
核心:
用一台可共享、大容量、高速的块设备,来模拟独占设备的操作,这样独占设备变成多台可并行 的虚拟设备,逻辑上成为共享设备
spooling系统的组成:
输入井、输出井:磁盘上的
输入缓冲区、输出缓冲区:内存上的
软件资源 - 文件管理
软件:
程序(汇编程序 编译程序 链接程序)
子程序
应用程序
数据
文件分类:
按性质用途
系统文件:仅系统调用,不能读写、修改
库文件:用户可调用,不能被修改
用户文件
按数据
源文件:ASCII 汉字 .c asm
目标文件:01二进制
可执行文件:编译后的01二进制
按保护方式
只读文件
读写文件
可执行文件
不保护文件
按信息流向
输入文件
输出文件
输入输出文件
按存放时限
临时文件
永久文件
档案文件:日志
按文件组织
普通文件
目录文件
特别文件
文件系统模型:
文件系统组成:
文件组织
文件存取
文件控制
文件使用
文件的结构=组织方式:
逻辑结构
物理结构
逻辑结构:
有结构=记录式文件
无结构=流式文件
有结构文件:
顺序文件
索引文件
索引顺序文件
文件存取:
顺序存取(数组顺序)
直接存取=随机存取(链表)
按键存取(哈希)
文件物理结构
文件存储设备(介质):
磁盘 磁带 光盘
文件物理结构
连续结构
链式结构(链表)
索引结构(哈希、页表、段表)
文件记录的成组、分解
逻辑记录的大小常小于实际物理块大小
成组:多个逻辑记录放在一个物理块中
分解:物理块中某个逻辑记录分离出来
文件管理,使 用户方便安全使用信息资源,包括:
管理 目录
管理 文件存储空间
文件共享
文件读写管理保护
文件操作:创建create
、打开open
、读写read write
、关闭close
、删除delete
文件控制块FCB
:
描述、控制文件的数据结构,与文件一一对应
目录:文件控制块的有序集合
目录项:目录中的每一个文件控制块
目录结构:
一级目录结构
二级目录结构
多级目录结构
一级目录结构
优点:结构简单
缺点:
查找速度慢
不能重名
共享不方便
二级目录结构
MFD 主文件目录
UFD 用户文件目录
优点(克服了一级目录的缺点)
提高检索速度
解决了不能重名问题
缺点:
不够灵活
无法反映多道程序设计中复杂的文件组织形式
多级目录结构
目录查询:
线性检索
哈希
类似于内存管理
为新创建的文件分配存储空间
连续 :分配速度高,有碎片
离散:分配速度低,无碎片
空间分配的基本单位(交换):磁盘块
文件存储空间管理就是对空闲块的管理
3个办法:
空闲块表法
空闲块链法
位示图法
空闲块表法:
空闲块链法:
位示图法:
0:空闲
1:占用
i
行j
列,对应盘块号 b=n(i-1)+j
n
:每行的位数
回收时
i=(b-1)/n+1
j=(b-1)%n+1
早期的方法:
绕道法、链接法、基本文件目录表法
绕道法:
文件中没有共享文件,就向上寻找到交叉点
,在向下访问到共享文件
链接法:
基本文件目录表法:
基本文件目录BFD
现在共享的方法:
基于索引节点,符号链接
扩展:
https://www.cnblogs.com/life-of-coding/p/10871831.html
https://www.icoa.cn/a/910.html
基于索引节点 = 硬链接
硬链接:
给文件的数据多创建了一个“入口”,
“A.txt”,“B.txt”指向硬盘的同一块区域,因此这两文件的内容一样,
编辑任何一个文件会影响另一文件,删除一个文件,只是删除这个文件其中一个“入口”,要两个文件都删除,文件系统才会标志这块硬盘区域上的文件被删除。
符号链接
b想共享a的文件,在b中给出a文件的路径,要使用时,根据路径去寻找文件即可
防止文件用户 或其他用户 对文件的破坏
破坏:
系统硬件故障
软件故障
用户文件共享引起的错误
防止 系统硬件故障:
建立副本
定期转储
建立副本:
适合小的、极重要的文件
定期转储:
海量转储 = 全量转储
增量转储
海量转储:
定期 把所有文件复制到大存储中
缺点:
转储过程该文件不能有任何操作(读写)
转储时间长
增量转储:
把更新的文件转储到大存储器中
若发生文件损坏,解决办法:
1全量存储:把最近一次全量转储装入该文件中
2 增量存储:由近及远恢复文件
3 在最近一次的全量存储中,恢复未被恢复的文件
防止文件共享引起的错误:
存取控制矩阵
存取控制表
用户权限表
存取控制矩阵:
每个用户对每个文件的访问权限
存取控制表:
每个用户对每一类文件的访问权限
用户权限表
某一个用户对它要访问的每一个文件的访问权限
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。