操作系统1(OS,operating system)

OS 概论

计算机由外到内:
多个用户
各个软件
操作系统
硬件

OS 目标 作用

操作系统目标:
方便(对用户)
有效(能运行用户的程序;高效,对系统)
可扩充(低成本、高质量地在现有系统中添加新功能和优化现有功能)
开放性(人们可以通过自己编写软件来扩充系统的功能,实现复杂的计算)

现代OS主要目标:
提高资源利用率
方便用户

操作系统作用:
是接口,是用户和计算机硬件系统之间的接口
实现了计算机资源的抽象
管理者,是计算机资源的管理者
组织者,是计算机工作流程的组织者(为众多作业切换处理机,协调它们的推进进度,提升系统性能)

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
微内核结构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个就减少1if(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关联的队列中等待的所有进程移除到就绪队列中
	}	
}

死锁 deadlock

产生原因:
竞争资源
推进顺序非法

产生死锁必要条件:
互斥
请求和保持
不剥夺
环路等待

破解死锁:

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
		序列不安全

3个经典同步问题:

生产者消费者、哲学家进餐、读者写者问题

生产者消费者问题:
缓冲区大小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=1nTi

单个作业 带权周转时间:
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=1nWi

响应时间:
响应时刻 − - 键盘输入时刻

截止时间:
开始截止时间、完成截止时间

进程 线程 管程 协程

程序顺序执行特征:
顺序
封闭
可再现性
独享资源

并发:同一时间间隔内交替执行

程序并发执行特征 = 程序不能并发执行的原因
间断:执行 间断 执行
不封闭:一个程序会受其他程序影响
结果不可再现:一个程序重复执行,结果不同
共享资源

进程引入的目的:
内存中的多道程序能正确的并发执行
提高资源利用率、提高系统的效率

线程引入目的:
减少程序并发而付出的时空开销
并发程度更好

没有进程的程序不能并发执行的原因 = 程序并发执行特征

进程的几个定义:(进程 程序)
1 是程序的一次执行
2 是程序、其数据在处理机上顺序执行所发生的活动
是程序在一个数据集合上运行的过程
是进程实体的运行过程
3 是CPU调度的 分配单位

线程定义:
进程内的执行单位 = 进程内可调度法实体
是CPU调度 的执行单位

线程包含线程

进程的组成:
机器指令、数据、堆栈、进程控制块PCB

线程组成:
线程标识符、程序计数器、寄存器、堆栈

线程3个基本状态:
就绪:就差CPU了
执行:就绪 + CPU = 开始执行
阻塞:正在执行,因某事件而暂停

进程特征:
并发:多个进程一段时间同时执行
异步:多道程序环境,每个程序何时执行、暂停 均未知,但结果可再现
动态:程序执行过程动态
独立:各个实体独立的 运行、分配资源、接受调度

OS 基本特征:
并发、异步、共享、虚拟

处理机执行状态:
系统态、用户态;

系统态 = 核心态 = 内核态 = 管态:
权限高,访问、执行一切指令和区域;

用户态 = 目态:
权限低,访问、执行部分指令和区域

线程:
用户级线程、内核支持线程

用户级线程:
线程仅在用户级中,线程的 创建 撤销 切换 不通过OS内核执行
切换速度块

内核支持线程:
线程在内核中,线程的 创建 撤销 切换 通过OS内核执行

内核级 相对 用户级线程 的优势:
同一进程的多个线程可以在多个处理器中
一个线程被阻塞,内核可以调度同一进程的其他线程
内核本身也可以用多线程实现

缺点:
速度、效率不如用户级
其原因是:
即使CPU在同一进程多个线程之间切换,也要陷入内核

陷入内核:

管程

管程引入目的:
信号量机制的缺点:
进程自备同步操作,P(S)和V(S)操作大量分散在各进程中,不易管理,容易死锁

定义:
是软件模块:包含 局部于自己的公共变量 + 所有访问公共变量的过程所

管程组成:
1 局部于管程的共享变量
2 对数据结构进行操作的过程
3 对局部于管程的数据进行初始化的语句

管程的属性:
共享、互斥
安全
封装

共享、互斥:
管程可被进程互斥访问,属于共享资源

安全:
管程局部变量只能被管程的过程访问,不允许进程、其它管程直接访问
管程不能访问不属于它的变量

封装:
管程内的数据结构是私有的,只能在管程内使用,管程内的过程也只能使用管程内的数据结构。
进程通过调用管程的过程使用临界资源

协程

进一步提高系统并发数量,对线程进一步分割,这就是协程

进程控制块 PCB

进程控制块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是回收的:

用动态重定位

存储保护:
限界寄存器,进程运行时,基址寄存器放分区地址(首地址),限界寄存器放分区最后一个存储单元地址

缺点:
动态算法复杂
存在碎片,回收空闲分区要分区合并,系统开销大

伙伴系统
每次对一个作业要装入内存,若作业大小要小于可用内存的一半,内存大小分为两半,一个给作业

内存扩充 (对换、覆盖):

对换、覆盖
对换、覆盖可对内存进行逻辑扩充

对换:
内存种暂时不能运行的进程、程序、数据转到外存中

整体对换=进程对换:
以整个进程为单位
页面对换=分段对换=部分对换:
以 页 段 为单位

覆盖:
小内存运行大作业不再是空想
将程序分成几个功能独立的程序段,根据程序的逻辑结构,不能同时执行的程序段共享相同的内存区域

对换与覆盖异同点:

结构不同
对换:不要求程序员给出程序段之间的交换通道结构
覆盖:要求程序员在程序段之间提供覆盖结构

单位不同
对换的范围:进程或作业之间的交换
覆盖的范围:相同的过程中进行

效果不同
对换:单进程大小 < 内存实际大小
覆盖:单进程大小 > 内存实际大小 是允许的

分页 page

页、页长、页号:
针对作业进行划分,每一部分大小相等( 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)、主存储器外的其他硬件,所以磁盘就是外部设备,也行吧。。。

磁盘空间管理

磁盘空间管理 = 文件空间管理
点我 文件空间管理

磁盘调度

磁盘调度:减少磁盘平均寻道时间,减少磁头移动总量
先来先服务 FCFSfirst come first service
最短时间寻道优先 SSTFShortest Seek Time First
扫描法 SCAN
循环扫描法 CSCANcirculate scan
N-Step-SCAN 算法

扫描法 SCAN
沿着磁头移动方向,选择距其最近的请求,磁头到底,反方向移动

循环扫描法 CSCANcirculate scan):
沿着磁头移动方向,选择距其最近的请求,磁头到底,从头开始移动,移动方向没变

N-Step-SCAN 算法:
磁盘请求队列分成n个子队列,按FCFS处理子队列。
每处理一个子队列时,按SCAN算法

设备管理 I/O

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系统

SPOOLing系统 = 假脱机技术 = 外部设备同时联机操作
Simultaneous Peripheral Operations On-Line
核心:
用一台可共享、大容量、高速的块设备,来模拟独占设备的操作,这样独占设备变成多台可并行 的虚拟设备,逻辑上成为共享设备

spooling系统的组成:

输入井、输出井:磁盘上的
输入缓冲区、输出缓冲区:内存上的

文件管理

软件资源 - 文件管理

软件:
程序(汇编程序 编译程序 链接程序)
子程序
应用程序
数据

文件分类:

按性质用途
系统文件:仅系统调用,不能读写、修改
库文件:用户可调用,不能被修改
用户文件

按数据
源文件:ASCII 汉字 .c asm
目标文件:01二进制
可执行文件:编译后的01二进制

按保护方式
只读文件
读写文件
可执行文件
不保护文件

按信息流向
输入文件
输出文件
输入输出文件

按存放时限
临时文件
永久文件
档案文件:日志

按文件组织
普通文件
目录文件
特别文件

文件系统模型:

文件系统组成:

文件组织
文件存取
文件控制
文件使用

文件的结构=组织方式:
逻辑结构
物理结构

逻辑结构:
有结构=记录式文件
无结构=流式文件

有结构文件:
顺序文件
索引文件
索引顺序文件

文件存取:
顺序存取(数组顺序)
直接存取=随机存取(链表)
按键存取(哈希)

文件物理结构
文件存储设备(介质):
磁盘 磁带 光盘

文件物理结构
连续结构
链式结构(链表)
索引结构(哈希、页表、段表)

文件记录的成组、分解
逻辑记录的大小常小于实际物理块大小
成组:多个逻辑记录放在一个物理块中
分解:物理块中某个逻辑记录分离出来

文件管理,使 用户方便安全使用信息资源,包括:
管理 目录
管理 文件存储空间
文件共享
文件读写管理保护
文件操作:创建create、打开open、读写read write、关闭close、删除delete

目录管理

文件控制块FCB
描述、控制文件的数据结构,与文件一一对应

目录:文件控制块的有序集合
目录项:目录中的每一个文件控制块

目录结构:
一级目录结构
二级目录结构
多级目录结构

一级目录结构

优点:结构简单

缺点:
查找速度慢
不能重名
共享不方便

二级目录结构
MFD 主文件目录
UFD 用户文件目录

优点(克服了一级目录的缺点)
提高检索速度
解决了不能重名问题

缺点:
不够灵活
无法反映多道程序设计中复杂的文件组织形式

多级目录结构

目录查询:
线性检索
哈希

文件存储空间管理

类似于内存管理

为新创建的文件分配存储空间
连续 :分配速度高,有碎片
离散:分配速度低,无碎片

空间分配的基本单位(交换):磁盘块

文件存储空间管理就是对空闲块的管理

3个办法:
空闲块表法
空闲块链法
位示图法

空闲块表法:

空闲块链法:

位示图法:

0:空闲
1:占用
ij列,对应盘块号 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 在最近一次的全量存储中,恢复未被恢复的文件

防止文件共享引起的错误:
存取控制矩阵
存取控制表
用户权限表

存取控制矩阵:

每个用户对每个文件的访问权限

存取控制表:

每个用户对每一类文件的访问权限

用户权限表

某一个用户对它要访问的每一个文件的访问权限

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_1403034144

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值