Commit 97404e32 authored by 一只荆棘鸟's avatar 一只荆棘鸟
Browse files

Update 4 files

- /chapter4-设备管理/实验7--磁盘调度算法--SSTF/原理解释.rst
- /chapter4-设备管理/实验7--磁盘调度算法--SSTF/代码实现.cpp
- /chapter4-设备管理/实验7--磁盘调度算法--SSTF/实验结果示例.rst
- /appendix4/SSTF.png
parent ae858a4d
No related merge requests found
Showing with 198 additions and 0 deletions
+198 -0
appendix4/SSTF.png

51.5 KB

#include <iostream>
#include <vector>
#include <algorithm>
#include <stdexcept>
#include <fstream>
using namespace std;
// 磁盘请求类,包含请求的ID和目标磁道号
class DiskRequest {
public:
int id;
int track;
DiskRequest(int id, int track) : id(id), track(track) {}
};
// 磁盘调度器类
class DiskScheduler {
private:
vector<DiskRequest> requestQueue; // 请求队列
int currentTrack; // 当前磁头所在的磁道
ofstream logFile; // 日志文件
public:
DiskScheduler() : currentTrack(0) {
logFile.open("sstf_log.txt", ios::out);
if (!logFile.is_open()) {
throw runtime_error("无法打开日志文件");
}
}
~DiskScheduler() {
if (logFile.is_open()) {
logFile.close();
}
}
// 添加请求到队列
void addRequest(const DiskRequest &request) {
requestQueue.push_back(request);
logFile << "请求已添加: ID=" << request.id << ", 磁道=" << request.track << "\n";
}
// 处理所有请求
void processRequests() {
while (!requestQueue.empty()) {
auto closestRequest = findClosestRequest();
logFile << "处理请求: ID=" << closestRequest.id << ", 磁道=" << closestRequest.track << "\n";
moveToTrack(closestRequest.track);
logFile << "请求已完成: ID=" << closestRequest.id << "\n";
cout << "已处理请求: 磁道=" << closestRequest.track << endl;
removeRequest(closestRequest);
}
}
// 找到距离当前磁头最近的请求
DiskRequest findClosestRequest() {
if (requestQueue.empty()) {
throw runtime_error("请求队列为空");
}
auto closest = requestQueue.begin();
int minDistance = abs(closest->track - currentTrack);
for (auto it = requestQueue.begin(); it != requestQueue.end(); ++it) {
int distance = abs(it->track - currentTrack);
if (distance < minDistance) {
closest = it;
minDistance = distance;
}
}
return *closest;
}
// 将磁头移动到指定的磁道
void moveToTrack(int track) {
if (track < 0) {
throw invalid_argument("磁道号不能为负数");
}
logFile << "从磁道 " << currentTrack << " 移动到磁道 " << track << "\n";
currentTrack = track;
}
// 从请求队列中移除已处理的请求
void removeRequest(const DiskRequest &request) {
auto it = find_if(requestQueue.begin(), requestQueue.end(), [&request](const DiskRequest& r) {
return r.id == request.id;
});
if (it != requestQueue.end()) {
requestQueue.erase(it);
} else {
throw runtime_error("请求未找到,无法移除");
}
}
// 打印当前磁头所在的磁道
void printStatus() const {
cout << "当前磁道: " << currentTrack << "\n";
}
};
int main() {
try {
DiskScheduler scheduler;
// 添加一些请求
scheduler.addRequest(DiskRequest(1, 98));
scheduler.addRequest(DiskRequest(2, 183));
scheduler.addRequest(DiskRequest(3, 37));
scheduler.addRequest(DiskRequest(4, 122));
scheduler.addRequest(DiskRequest(5, 14));
scheduler.addRequest(DiskRequest(6, 124));
scheduler.addRequest(DiskRequest(7, 65));
scheduler.addRequest(DiskRequest(8, 67));
// 处理所有请求
scheduler.processRequests();
// 打印最终状态
scheduler.printStatus();
} catch (const exception &e) {
cerr << "错误: " << e.what() << "\n";
}
return 0;
}
SSTF(Shortest Seek Time First)
===============================
原理
----
SSTF(Shortest Seek Time First)调度算法是一种磁盘调度算法,它优先处理离当前磁头位置最近的请求,以最小化磁头的移动时间。该算法通过选择寻道时间最短的请求来减少平均寻道时间。
执行过程
--------
1. **请求到达**:
- 当系统中的进程需要进行磁盘操作时,会向磁盘调度器发出读写请求。
- 这些请求会按照它们的目标磁道号记录下来。
2. **选择最近请求**:
- 磁盘调度器从所有未处理的请求中选择离当前磁头位置最近的请求。
- 寻找最小的磁道差值,即绝对值最小的目标磁道号与当前磁头位置之差。
3. **请求处理**:
- 处理选定的请求,移动磁头到该请求的目标磁道。
- 将该请求标记为已处理,并从未处理的请求列表中移除。
4. **重复过程**:
- 重复步骤2和步骤3,直到所有请求都被处理完毕。
优点
----
- **减少平均寻道时间**:通过优先处理最近的请求,SSTF算法可以显著减少磁头的总移动距离,从而降低平均寻道时间。
- **提高效率**:相比FCFS算法,SSTF通常能更有效地利用磁盘,提高系统的响应速度。
缺点
----
- **可能导致饥饿**:如果有大量的请求集中在某个磁道附近,离该区域较远的请求可能会长时间得不到处理,从而导致饥饿问题。
- **实现复杂**:相比于FCFS算法,SSTF需要实时计算每个请求与当前磁头位置的距离,增加了实现的复杂度。
示例
----
假设请求到达的顺序和它们所在的磁道如下:
- 请求1:磁道98
- 请求2:磁道183
- 请求3:磁道37
- 请求4:磁道122
- 请求5:磁道14
- 请求6:磁道124
- 请求7:磁道65
- 请求8:磁道67
当前磁头位置在磁道53,按照SSTF算法的处理顺序如下:
1. 从53到65(最近的请求)
2. 从65到67
3. 从67到37
4. 从37到14
5. 从14到98
6. 从98到122
7. 从122到124
8. 从124到183
通过这种顺序,SSTF算法减少了磁头的总移动距离。
.. image:: ../../../appendix4/SSTF.png
:width: 400px
:alt: Process States Diagram
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment