

# 文件系统

# 文件命名

<table><tr><td>扩展名</td><td>含 义</td></tr><tr><td>file.bak</td><td>备份文件</td></tr><tr><td>file.c</td><td>C源程序文件</td></tr><tr><td>file.gif</td><td>符合图形交换格式的图像文件</td></tr><tr><td>file.hlp</td><td>帮助文件</td></tr><tr><td>file.html</td><td>WWW超文本标记语言文档</td></tr><tr><td>file.jpg</td><td>符合JPEG编码标准的静态图片</td></tr><tr><td>file.mp3</td><td>符合MP3音频编码格式的音乐文件</td></tr><tr><td>file.mpg</td><td>符合MPEG编码标准的电影</td></tr><tr><td>file.o</td><td>目标文件(编译器输出格式,尚未连接)</td></tr><tr><td>file.pdf</td><td>pdf格式的文件</td></tr><tr><td>file.ps</td><td>PostScript文件</td></tr><tr><td>file.tex</td><td>为TEX格式化程序准备的输入文件</td></tr><tr><td>file.txt</td><td>一般正文文件</td></tr><tr><td>file.zip</td><td>压缩文件</td></tr></table>

# 文件结构：

字节序列、记录序列、树

1. 无结构的字节序列

![](images/b464b4362a2fe89910a9e4b68027cab3ad7ea56317c34a52fb3c0cbe2fcb1a58.jpg)

2. 记录序列 有固定格式 ,基于
3. 树形结构

由一棵记录树构成

# 文件类型

- 普通文件

​	ASCII文件、二进制文件

- 目录文件

- 特殊文件

​	字符特殊文件、块设备特殊文件

特殊文件：前者鼠标键盘后者磁盘

Gcc -o hello hello.c 可执行的文件就是二进制文件 ELF 格式

目录文件~文件夹

文件访问

顺序访问

从文件开始按顺序读取文件的全部字节或记录，不能跳过某一些内容

随机访问

能够以任何次序读取其中字节或记录的文件称为随机访问文件

文件属性（元数据）

<table><tr><td>属性</td><td>含义</td></tr><tr><td>保护</td><td>谁可以存取文件,以什么方式存取文件</td></tr><tr><td>口令</td><td>存取文件需要的口令</td></tr><tr><td>创建者</td><td>创建文件者的ID</td></tr><tr><td>所有者</td><td>当前所有者</td></tr><tr><td>只读标志</td><td>0表示读/写;1表示只读</td></tr><tr><td>隐藏标志</td><td>0表示正常;1表示不在列表中显示</td></tr><tr><td>系统标志</td><td>0表示普通文件;1表示系统文件</td></tr><tr><td>存档标志</td><td>0表示已经备份;1表示需要备份</td></tr><tr><td>ASCII/二进制标志</td><td>0表示ASCII码文件;1表示二进制文件</td></tr><tr><td>随机存取标志</td><td>0表示只允许顺序存取;1表示随机存取</td></tr><tr><td>临时标志</td><td>0表示正常;1表示进程退出时删除该文件</td></tr><tr><td>加锁标志</td><td>0表示未加锁;非零表示加锁</td></tr><tr><td>记录长度</td><td>一个记录中的字节数</td></tr><tr><td>键的位置</td><td>每个记录中键的偏移量</td></tr><tr><td>键的长度</td><td>键字段的字节数</td></tr><tr><td>创建时间</td><td>文件创建的日期和时间</td></tr><tr><td>最后一次存取时间</td><td>文件上一次存取的日期和时间</td></tr><tr><td>最后一次修改时间</td><td>文件上一次修改的日期和时间</td></tr><tr><td>当前大小</td><td>文件的字节数</td></tr><tr><td>最大长度</td><td>文件可能增长到的字节数</td></tr></table>

1.  文件名：由创建文件的用户决定文件名  
2. 标识符:标识符是操作系统用于区分各个文件的一种内部名称  
3. 类型：文件的类型  
4. 位置：存放的路径

无结构文件：由一些二进制或字符流组成，又称“流式文件“

有结构文件：由一个个记录组成

文件之间应该怎样组织起来？



用户可以自己创建一层一层的目录，各层目录中存放相应的文件。系统中的各个文件就通过一层一层的目录合理有序的组织起来了.

目录其实也是一种特殊的有结构文件(由记录组成)，如何实现文件目录是之后会重点探讨的问题.

所谓的“目录”其实就是我们熟悉的“文件夹”。

![image-20260420001931583](https://chenalna.oss-cn-hangzhou.aliyuncs.com/img/image-20260420001931583.png)

![image-20260420001936314](https://chenalna.oss-cn-hangzhou.aliyuncs.com/img/image-20260420001936314.png)

创建文件(create系统调用)

删除文件(delete系统调用)

读文件(read系统调用)

写文件(write系统调用)

打开文件(open系统调用)

关闭文件(close系统调用)



从上往下，文件应该如何存放在外存

物理地址

0-1023 0号块

1024-2047 1号块

...

外存（磁盘）

操作系统以“块”为单位为文件分配存储空间，因此即使一个文件大小只有10B，但它依然需要占用1KB的磁盘块。外存中的数据读入内存时同样以块为单位
。

类似于内存分为一个个“内存块”，外存会分为一个个“块/磁盘块/物理块”。每个磁盘块的大小是相等的，每块一般包含2的整数幂个地址(如本例中.一块包含$2^{10}$个地址，即1KB)。同样类似的是，文件的逻辑地址也可以分为(逻辑块号，块内地址)，操作系统同样需要将逻辑地址转换为外存的物理地址(物理块号，块内地址)的形式。块内地址的位数取决于磁盘块的大小
.

与内存一样，外存也是由一个个存储单元组成的，每个存储单元可以存储一定量的数据(如1B)。每个存储单元对应一个物理地址。

# 文件的逻辑结构

逻辑上可以相邻，物理结构可以不相邻

无结构文件

# 文件的物理结构

文件最后时存储在磁盘上，要读到内存里

磁盘分配空间

连续分配

链接分配

索引分配

连续分配

连续文件又称为顺序文件，它把逻辑文件中的信息顺序地存放到一组相邻接的磁盘块

内存与外存以块位单位传递数据

![](images/221571589ca3c06544fd3a9b7448e9fb6c292fd1d7b9ce40ce811cc084fcf1fc.jpg)

文件的逻辑地址也可以表示为（逻辑块号，块内地址）的形式

# 连续分配

要实现逻辑地址到物理地址的映射

![](images/3006f13db25abdf16b60ea993a03b02ac91798731b4eff30e6b37a75ace186b3.jpg)

![](images/21fe7e26835c77cc107ceb08ae2d0464d4ce8ecbe30a66270a0e06ab6c121e1e.jpg)

![](images/f55df14d2b6431be7658334bfd953833083da8566e63f89e0c089bd0e54e751a.jpg)

扇区：磁盘访问的最小单位

簇(cluster)：由多个扇区组成也称为磁盘块

优点:支持顺序访问和随机访问，顺序访问更快

缺点：需要连续的存储空间，确定一个文件需要多少空间

![](images/82b7c873ed58dfb1f99d818c77feb3ac3ce0df2738a2ec718885825417f284b6.jpg)

<table><tr><td>文件名</td><td>......</td><td>起始块号</td><td>长度</td></tr><tr><td>aaa</td><td>...</td><td>4</td><td>3</td></tr><tr><td>bbb</td><td>...</td><td>10</td><td>4</td></tr><tr><td>......</td><td>...</td><td>...</td><td>...</td></tr></table>

文件目录中记录存放的起始块号和长度

CD-ROM

扇区：512B

# 链式分配

![](images/d76cdf841fc51cd71e1e65a6e890e4d95125937f42959111c8137c2089026605.jpg)

# 索引分配

# 隐式链接

![](images/0eb7cca7f37f86fa2d710ee80c01d8e0876e05525acc9cc7a61bd0292bba9dcd.jpg)

索引分配：将所有指针放在一起

索引块：磁盘块地址的数组

优点：支持随机访问，没有碎片

缺点：索引块浪费时间

索引块应该设为多大



# 显式链接

把物理块的指针显示地存放在一张表中，**即文件分配表**

一个磁盘仅设置一张FAT，常驻内存

支持随机访问

不需要访问磁盘



![](images/331cf78a06752c6a929f5d56d7c4a48df2790d01c0cd19f508cfa670f32b0be8.jpg)

指针：磁盘块地址

解决方案：

1. 链接方案：如果索引表太大，那么可以将多个索引块链接起来存放

2. 

# 多级索引

![](images/e280a383db867ccc97eee2b5202599212473573c6d528aa9dd58f9e993d71add.jpg)

建立多层索引，类似于多级页表，使第一层索引块指向第二层的索引块。

文件大小的要求再建立第三层、第四层索引块。

![](images/fc08a8388773bdc2a81ddd06eb258ebed0de11948d88f9cf2a2a900d1f0d0d18.jpg)

假设磁盘块大小为1KB，一个索引表项占4B，则一个磁盘块只能存放256个索引项。

若某文件采用两层索引，则该文件的最大长度可以到256\*256*1KB = 65,536 KB = 64MB

可根据逻辑块号算出应该查找索引表中的哪个表项。如:要访问1026号逻辑块，则1026/256 = 4. 1026%256 = 2

因此可以先将一级索引表调入内存，查询4号表项，将其对应的二级索引表调入内存，再查询二级索引表的2号表项即可知道1026号逻辑块存放的磁盘块号了。

访问目标数据块，需要3次磁盘/O。

混合索引

![](images/c51396610d11cd4829091a4eb11ce03671bd4cc3687292231b44292b2090fcb6.jpg)

![](images/400072df8da19987149265a7a11a1d905eebeaf12e7302b10a5376e852aa341e.jpg)

成组链接法

![](images/3ac5a4da438dc4652322377ae219cc6c94a0073a32ccc34bd0c7f9c8037bc76d.jpg)

文件



![](images/c340e7d0e17bfff1f393c49f123348edeeb66527cd16927c864cef59cf893946.jpg)

文件主标识符、类型、存取权限、物理地址、文件长度、链接计数、存取时间



文件控制块FCB

文件和文件控制块一一对应，文件控制块的有序集合称为文件目录

有的书中提到一个文件控制块是一个文件目录项

FCB通常包括以下三类信息：

·基本信息，例如文件名、文件的物理位置等  
·存取控制信息，指的是文件的存取权限  
·使用信息，例如文件的建立时间、修改时间等

![](images/beb79d86c95619c9efb114613c661d2669cea30cd98108afd462b6a4a3073429.jpg)

FCB 的有序集合称为文件目录（目录文件），一个 FCB 就是一个文件目录项

目录文件中的一条记录就是一个 FCB

也叫做文件控制块

单级目录结构

![](images/6269c7f47662629eef60421179541bd062e53e3f74a0a0fe4d5f5f6aa0ccb4e2.jpg)



单级目录实现了“按名存取”，但是不允许文件重名。

在创建一个文件时，需要先检查目录表中有没有重名文件，确定不重名后才能允许建立文件，并将新文件对应的目录项插入目录表中。

显然，单级目录结构不适用于多用户操作系统。

# 两级目录结构

MFD 主文件目录

UFD 用户文件目录

![](images/946d22b9086a04f7acb2900659ce77455de57a8a18708e85754a9353486f4fdb.jpg)

# 多级目录，又称树形目录

要访问某个文件时要用文件路径名标识文件，文件路径名是个字符串

无环图目录结构

![](images/8665ab96752d9ac70ef91a5c98199e200d9ebac92a360b58f55148478560532f.jpg)

可以用不同的文件名指向同一个文件，甚至可以指向同一个目录(共享同一目录下的所有内容)。

需要为每个共享结点设置一个共享计数器，用于记录此时有多少个地方在共享该结点。用户提出删除结点的请求时，只是删除该用户的FCB、并使共享计数器减1，并不会直接删除共享结点。

只有共享计数器减为0时，才删除结点。

注意:共享文件不同于复制文件。在共享文件中，由于各用户指向的是同一个文件，因此只要其中一个用户修改了文件数据，那么所有用户都可以看到文件数据的变化。

# 索引节点

文件目录（文件夹）也是一种文件，需要存放在磁盘上

当文件很多时，文件目录要占用大量的盘块

在检索目录文件的时候，需要将目录调入内存，然后比较文件名

但是只是用到文件名，而不需要其他的文件信息

文件名和文件信息分来，将文件描述信息单独存放在索引节点中

FCB =文件名+索引节点

索引节点(FCB的改进)

<table><tr><td>文件名</td><td>索引结点指针</td></tr><tr><td>qianlong</td><td></td></tr><tr><td>QMDownLoad</td><td></td></tr><tr><td>......</td><td></td></tr><tr><td>照片</td><td></td></tr><tr><td>......</td><td></td></tr><tr><td>对账单4.txt</td><td></td></tr></table>



索引结点（包含了除文件名之外的文件描述信息）



假设一个FCB是64B，磁盘块的大小为1KB，则每个盘块中只能存放16个FCB。若一个文件目录中共有640个目录项，则共需要占用640/16=40个盘块。因此按照某文件名检索该目录，平均需要查满320个目录项，平均需要启动磁盘20次（每次磁盘I/O读入一块）

若使用索引结点机制，文件名占14B，索引结点指针站2B，则每个盘块可存放64个目录项，那么按文件名检索目录平均只需要读入320/64 =5个磁盘块，这将大大提升文件检索速度。

当找到文件名对应的目录项时，才需要将索引节点调入内存；索引节点中记录了文件的各种信息，包括文件在外存中的存放位置，根据“存放位置”即可找到文件。

# 文件操作

创建文件(creat open+特定标记)

读文件

写文件

删除文件

截断文件

# 创建文件



创建一个文件，可以通过系统调用open实现Creat

int fd=open("path",O_CREAT|O_WRONLY|O_TRUNC);

系统调用open返回值——文件描述符（file description）

·文件描述符是一个整数，是每个进程私有的  
·文件描述符可以理解为一种权限，允许执行某些操作  
·将文件描述符看成指向文件类型对象的指针  
·每一个进程通过一个文件描述符表记录打开的文件

# 对文件的读写通过文件描述符来访问

```c
int open(char*filenameint flags, modet mode);
ssize t read(int fd, void *buf, size_t n);
ssize_t write(int fd, const void *buf, size_t n);
int close (int fd);
```



关闭后，该文件描述符从文件描述符表中删除

# 目录文件—— 文件夹，目录文件的位置

文件系统通常使用目录(文件夹）记录文件的位置

目录包含一个文件名的列表，每个文件名对应一个inode编号

每个文件名称为目录项，每个名字到inode的映射称为链接

```c
struct dirent {
    ino_t d_ino; /* inode number */
    char d_name[256]; /* Filename */
}; 
```

指向一个索引节点

FCB  =文件名 + 索引编号

文件目录结构

![](images/487ea92a3b1e8c07d01c474dca56fc312f5678cdde08fc2a5d29068bd3694f5e.jpg)

删除目录

创建目录

打开目录和关闭目录

文件链接

读目录项



目录中每个名字到索引节点的映射称为链接

链接的本质就是目录中一个指向索引节点(inode)的名字

所有的链接中，没有一个链接是“原始”或者“初始”状态

硬链接

\> ln /oldpath /newpath

int link(const char\*oldpath,const char\*newpath);



知识回顾：索引结点，是一种文件目录瘦身策略。由于检索文件时只需用到文件名，因此可以将除了文件名之外的其他信息放到索引结点中。这样目录项就只需要包含文件名、索引结点指针。

![](images/166de816abc717e1a52d850f68a1396621d596fc9dff96aad483b019fb5d90f6.jpg)

![](images/40703cd8300a3524f7a7b50221a5a394c5eadd4eca0df4815032768fa53466c4.jpg)

索引结点中设置一个链接计数变量count，用于表示链接到本索引结点上的用户目录项数。

若count $= 2$ ，说明此时有两个用户目录项链接到该索引结点上，或者说是有两个用户在共享此文件。若某个用户决定“删除”该文件，则只是要把用户目录中与该文件对应的目录项删除，且索引结点的count值减1。

若count>0，说明还有别的用户要使用该文件，暂时不能把文件数据删除，否则会导致指针悬空。

当count=0时系统负责删除文件。



同一个索引节点

共享文件

Copy和硬链接的区别？

Copy 是两份

硬链接只有一份，映射了同一索引节点

软链接（符号链接）

/> ln -s /oldpath /newpath

符号链接本身是一个不同类型的文件

普通文件、目录文件、符号链接

快捷方式

当前工作目录

每个进程都有一个当前目录一般是创建时从父进程继承的

内核解析相对路径时，会把当前工作目录作为起点

获得当前工作目录使用系统调用getcwd

```txt
char *getcwd(char *buf, size_t size); 
```

当前工作目录也可以修改

![](images/cd074b8c1b12f950507859590f3d24e850eb4026d208c9a5470bdea6a6b1a95a.jpg)

当User3访问“ccc”时，操作系统判断文件“ccc”属于Link类型文件，于是会根据其中记录的路径层层查找目录，最终找到User1的目录表中的“aaa”表项，于是就找到了文件1的索引结点。

# 存储空间管理

空闲空间管理  文件长度

为了追踪空闲的磁盘空间，系统需要维护一个空闲空间链表空闲空间链表记录了所有的空闲磁盘空间，也就是没有分配给文件和目录的空间

- 空闲表法
- 空闲链表法
- 位图法
- 成组链接法

#### 设备管理

设备的分类

1、按数据传输速率

低速：鼠标、键盘

中速：打印机、扫描仪

高速：磁盘

2、按信息交换单位

块设备：磁盘 可寻址

字符设备：不可寻址 中断驱动 交互式终端

3、按设备共享属性

4、按工作特性

存储设备

I/O 设备

网络通信设备

I/O 控制器/设备控制器

接受和识别命令

数据交换

地址识别

数据缓冲

识别和报告设备状态

差错控制

![](images/143ee3de398a9c2cbf0e7359815a65f1b8465f14a6e9d6b43f848bffbf3df9c7.jpg)

# 1、 一个 I/O 控制器可能会对应多个设备

# 2、内存映像I/O/寄存器独立编址

![](images/603ee7df80b4fe2bbccba8ff7c5b22bb3472cde0f1dc580a0c8726893375bae3.jpg)

I/O 控制方式

1、直接控制方式  
2、中断驱动控制方式  
3、 直接存储器存取

直接控制

![](images/4ba93ea783051ba8e6becb9c517d5547b3e00256583bfc811a334011333c9e91.jpg)

1、先经过 CPU，再到内存  
2、CPU干预的频率  
3、每次读写一个字  
4、缺点：CPU/I/O 设备只能串行工作，CPU 一直处于轮询状态

![](images/6b3faf37064d03f0743ea93ab83e3f5cd3479e9c0a30d4e23c0f81f99fcffd03.jpg)

中断驱动方式

由于I/O设备速度很慢，可将I/O等待的进程阻塞，现金切换到别的进程执行

![image-20260420125028408](https://chenalna.oss-cn-hangzhou.aliyuncs.com/img/image-20260420125028408.png)

# DMA 方式

与“中断驱动方式”相比，DMA方式（DirectMemoryAccess，直接存储器存取。主要用于块设备的1/O控制）有这样几个改进：

①数据的传送单位是“块”。不再是一个字、一个字的传送。

②数据的流向是从设备直接放入内存，或者从内存直接到设备。不再需要CPU作为“快递小哥”。 

③仅在传送一个或多个数据块的开始和结束时，才需要CPU干预。

![](images/097b9269cac00b912c89d878a106a8c979d61463dc902609bb9b85f3faa60750.jpg)

读取的时候是按字读取，然后放入内存以块为单位

仅在数据传送开始和结束时 caixuCPU 干预

![](images/d325b155f9dacbee21ecbb21b7dae752983351d221280f6e107bd2cea60ed8bc.jpg)

DR（DataBegister，数据寄存器）：暂存从设备到内存，或从内存到设备的数据  
MAB（MemoryAddressBeeister，内存地址寄存器）：在输入时，MAR表示数据应放到内存中的什么  
位置：输出时MAR表示要输出的数据放在内存中的什么位置。  
DC（DataCounter，数据计数器）：表示剩余要读/写的字节数。  
CR（CommandRegister，命令/状态寄存器）：用于存放CPU发来的I/O命令，或设备的状态信息。

缺点：只能处理离散的

# 通道控制方式：

一种硬件，识别并执行一系列通道指令。

通道：一种硬件，可以理解为是“弱鸡版的CPU”，通道可以是被并控制一系列通道指令

①CPU向通道发出I/O指令。指明通道程序在内存中的位置。并指明要操作的是哪个I/O设备，之后CPU就切换到其他进程执行了

②：通道执行内存中的通道程序（其中指明了要读入/写出多少数据，读/写的数据应该放在内存的什么位置等信息）

③：通道执行完规定的任务后，向CPU发出中断信号，之后CPU对中断进行处理

![image-20260420125304354](https://chenalna.oss-cn-hangzhou.aliyuncs.com/img/image-20260420125304354.png)

# 通道与CPU共享内存



通道:一种硬件，可以理解为是“弱鸡版的CPU”通道可以识别并执行一系列通道指令


与CPU相比，通道可以执行的指令很单一，并且通道程序是放在主机内存中的，也就是说通道与CPU共享内存

1.完成一次读/写操作的流程(见右图)

2.CPU干预的频率极低，通道会根据CPU的指示执行相应的通道程序，只有完成一组数据块的读/写后才需要发出中断信号，请求CPU干预。

3.数据传送的单位
每次读/写一组数据块

4.数据的流向(在通道的控制下进行)

读操作(数据输入):I/O-->设备内存

写操作(数据输出):内存-->I/O设备

5.主要缺点和主要优点缺点:实现复杂，需要专门的通道硬件支持

优点:CPU、通道、/O设备可并行工作，资源利用率很高

```mermaid
graph TD 
	A["CPU给通道发出指令"]-->B["CPU进行中断处理"]
	B-->C["执行后续操作"]
	A-->D["CPU做其它事情，通道自主完成I/O"]
	F["中断信号"]-->B
```





<table><tr><td></td><td>完成一次读/写的过程</td><td>CPU干预频率</td><td>每次I/O的数据传输单位</td><td>数据流向</td><td>优缺点</td></tr><tr><td>程序直接控制方式</td><td>CPU发出I/O命令后需要不断轮询</td><td>极高</td><td>字</td><td>设备→CPU→内存<br>内存→CPU→设备</td><td rowspan="4">每一个阶段的优点都是解决了上一阶段的最大缺点。总体来说，整个发展过程就是要尽量减少CPU对I/O过程的干预，把CPU从繁杂的I/O控制事务中解脱出来，以便更多地去完成数据处理任务。</td></tr><tr><td>中断驱动方式</td><td>CPU发出I/O命令后可以做其他事，本次I/O完成后设备控制器发出中断信号</td><td>高</td><td>字</td><td>设备→CPU→内存<br>内存→CPU→设备</td></tr><tr><td>DMA方式</td><td>CPU发出I/O命令后可以做其他事，本次I/O完成后DMA控制器发出中断信号</td><td>中</td><td>块</td><td>设备→内存<br>内存→设备</td></tr><tr><td>通道控制方式</td><td>CPU发出I/O命令后可以做其他事。通道会执行通道程序以完成I/O，完成后通道向CPU发出中断信号</td><td>低</td><td>一组块</td><td>设备→内存<br>内存→设备</td></tr></table>

# 磁盘调度算法

# FCFS

根循进程请求访问磁盈的光后顺序进仃调度。

假设磁头的初始位置是100号磁道，有多个进程先后陆续地请求访间55、58、39、18、90、160、

150、38、184号磁道

按照FCFS的规则，按照请求到达的顺序，磁头需要依次移动到55、58、39、18、90、160、150、

38、184号磁道

![](images/6715f8f83cf458bbc7ddd4001a87f4129740b242242103a801fc59efd71aef9d.jpg)

磁头总共移动了45+3+19+21+72+70+10+112+146=498个磁道

响应一个请求平均需要移动498/9=55.3个磁道（平均寻找长度）

优点：公平：如果请求访问的磁道比较集中的话，算法性能还算过的去

缺点：如果有大量进程竞争使用磁盘，请求访问的磁道很分散，则FCFS在性能上很差，寻道时间长。

SSTF算法会优先处理的磁道是与当前磁头最近的磁道。可以保证每次的寻道时间最短，但是并不能保证总的寻道时间最短。（其实就是贪心算法的思想，只是选择眼前最优，但是总体未必最优）

假设磁头的初始位置是100号磁道，有多个进程先后陆续地请求访问55、58、39、18、90、160、150、38、184号磁道

![](images/034efb01da8fe3382c42fb5418b56b2b04347c6621586962b3b364e200fd6a42.jpg)

磁头总共移动了（100-18）+（184-18）=248个磁道

响应一个请求平均需要移动248/9=27.5个磁道（平均寻找长度）

优点：性能较好，平均寻道时间短

缺点：可能产生“饥饿”现象

Eg：本例中，如果在处理18号磁道的访问请求时又来了一个38号磁道的访问请求，处理38号磁道的访问请求时又来了一个18号磁道的访问请求。如果有源源不断的18号、38号磁道的访问请求

到来的话，150、160、184号磁道的访问请求就永远得不到满足，从而产生“饥饿”现象。

SCAN

SSTF算法会产生饥饿的原因在于：磁头有可能在一个小区域内来回来去地移动。为了防止这个问题，可以规定，之哦有磁头移动到最外侧磁道的时候才能往内移动，移动到最内侧磁道的时候才能往外移动。这就是SCAN的思想。

假设某磁盘的磁道为0~200号，磁头的初始位置是100号磁道，且此时磁头正在往磁道号增大的方向移动，有多个进程先后陆续地请求访问55、58、39、18、90、160、150、38、184号磁道

![](images/022e70459533ed272df11792e4a197c8e65b09c84f920b183ddbc090d9cfa844.jpg)

磁头总共移动了（200-100）+（200-18）=282个磁道

响应一个请求平均需要移动282/9=31.3个磁道（平均寻找长度）

缺点：①只有到达最边上的磁道时才能改变磁头移动方向，事实上，处理了184号磁道的访问请求之后就不需要再往右移动磁头了。

②SCAN算法对于各个位置磁道的响应频率不平均（如：假设此时磁头正在往右移动，且刚处理过90号磁道，那么下次处理90号磁道的请求就需要等磁头移动很长一段距离：而响应了184号磁道的请求之后，很快又可以再次响应184磁道的请求。

# 注意接下来的LOOK调度算法才是教材里的SCAN算法

扫描算法（SCAN）中，只有到达最边上的磁道时才能改变磁头移动方向，事实上，处理了184号磁道的访问请求之后就不需要再往右移动磁头了。LOOK调度算法就是为了解决这个问题，如果在磁头移动方向上已经没有别的请求，就可以立即改变磁头移动方向（边移动边观察，因此叫LOOK）

假设某磁盘的磁道为0~200号，磁头的初始位置是100号磁道，且此时磁头正在往磁道号增大的方向移动，有多个进程先后陆续地请求访问55、58、39、18、90、160、150、38、184号磁道

![](images/b817c2c6022ab989fc9c805b054a0788978f98f45bb9e43e3201d0ffaea1b0a5.jpg)

磁头总共移动了（184-100)+（184-18)=250个磁道

响应一个请求平均需要移动 $2 5 0 / 9 = 2 7 . 5$ 个磁道（平均寻找长度）

优点：比起SCAN算法来，不需要每次都移动到最外侧或最内侧才改变磁头方向，使寻道时间进

# CSCAN 算法

SCAN算法对于各个位置磁道的响应频率不平均，而C-SCAN算法就是为了解决这个问题。规定只有磁头朝某个特定方向移动时才处理磁道访问请求，而返回时直接快速移动至起事端而不处理任何请求。

假设某磁盘的磁道为0~200号，磁头的初始位置是100号磁道，且此时磁头正在往磁道号增大移动，有多个进程先后陆续地请求访问55、58、39、18、90、160、150、38、184号磁道

![image-20260420125525402](https://chenalna.oss-cn-hangzhou.aliyuncs.com/img/image-20260420125525402.png)



只有到了最边上的磁道才能改变磁头移动方向，磁头返回途中不处理任何请求。

磁头总共移动了（200-100)+（200-0)+（90-0)=390个磁道

响应一个请求平均需要移动390/9=43.3个磁道（平均寻找长度）

优点：比起SCAN来，对于各个位置磁道的响应频率很平均。

注意接下来的C-LOOK调度算法才是我们教材中的的CSCAN算法

C-SCAN算法的主要缺点是只有到达最边上的磁道时才能改变磁头移动方向，并且磁头返回时不一定需要返回到最边缘的磁道上。C-LOOK算法就是为了解决这个问题。如果磁头移动的方向上已经没有磁道访问请求了，就可以立即让磁头返回，并且磁头只需要返回到有磁道访问请求的位置即可。

假设某磁盘的磁道为0-200号，磁头的初始位置是100号磁道，且此时磁头正在往磁道号增大的方向

移动，有多个进程先后陆续地请求访间55、58、39、18、90、160、150、38、184号磁道

![](images/0dfc46361cf1b6017a26cbbc71da325cdbe3b8dc68d72048025b36b1f71a3602.jpg)

假脱机技术：用ru

脱离主机的控制进行的输入/输出操作

在磁盘上开辟两个存储区域——输入井和输出井

外围控制机

假脱机技术，又称“SPOOLing”技术，用软件的方式模拟脱机技术。SPOOLing系统

"输入进程"模拟脱机输入时的外围控制机。

“输出进程“模拟脱机输出时的外围控制机。

![image-20260315112348221](https://chenalna.oss-cn-hangzhou.aliyuncs.com/img/image-20260315112348221.png)





输入井和输出井

内存中输入缓冲区、输入进程

输出缓冲区、输出进程

![image-20260315114705804](https://chenalna.oss-cn-hangzhou.aliyuncs.com/img/image-20260315114705804.png)







当多个用户进程提出输出打印的请求时，系统会答应它们的请求，但是并不是真正把打印机分配给他们，而是由假脱机管理进程为每个进程做两件事:

(1)在磁盘输出井中为进程申请一个空闲缓冲区(也就是说，这个缓冲区是在磁盘上的)，并将要打印的数据送入其中:

(2)为用户进程申请一张空白的打印请求表，并将用户的打印请求填入表中(其实就是用来说明用户的打印数据存放位置等信息的)，再将该表挂到假脱机文件队列上。

当打印机空闲时，输出进程会从文件队列的队头取出一张打印请求表，并根据表中的要求将要打印的数据从输出井传送到输出缓冲区，再输出到打印机进行打印。用这种方式可依次处理完全部的打印任务



杂项：

面对一般用户，通过操作命令控制操作系统

面对编程人员，通过系统调用控制

作业的输入方式有：联机输入,脱机输入,直接耦合,假脱机,网络输入

