实验一:进程调度模拟算法
一、实验目的
进程调度是处理机管理的核心内容。本实验要求用高级语言编写模拟进程调度程序,以便加深理解有关进程控制块、进程队列等概念,并体会和了解优先数算法和时间片轮转算法的具体实施办法。
二、实验要求
1.设计进程控制块 PCB 的结构,通常应包括如下信息: 进程名、进程优先数(或轮转时间片数)、进程已占用的 CPU 时间、进程到完成还需要的时间、进程的状态、当前队列指针等。
2.编写两种调度算法程序: 优先数调度算法程序 循环轮转调度算法程序
3.按要求输出结果。
三、实验过程
1.准备
A. 查阅相关资料:
B. 初步编写程序:
C. 准备测试数据:
D. 设计数据结构.
2.上机调试
4.主要流程和源代码
include
include
include
using namespace std;
// 进程控制块 PCB
struct PCB {
string name; // 进程名
int prio_round; // 优先数(优先算法)或时间片(轮转算法)
int cputime; // 已占用 CPU 时间片数
int needtime; // 到完成还需要的时间片数
char state; // 状态: 'R', 'W', 'F'
PCB* next; // 链表指针
PCB(string n, int pr, int need) : name(n), prio_round(pr), cputime(0), needtime(need), state('W'), next(nullptr) {}
};
// 全局指针
PCB* RUN = nullptr; // 当前运行进程
PCB* readyHead = nullptr; // 就绪队列头
PCB* readyTail = nullptr; // 就绪队列尾
PCB* finishHead = nullptr; // 完成队列头
PCB* finishTail = nullptr; // 完成队列尾
int algorithm = 1; // 1:优先数, 2:轮转
// ---------- 优先数算法:按优先数降序插入就绪队列 ----------
void INSERT1(PCB* p) {
p->next = nullptr;
if (readyHead == nullptr) {
readyHead = readyTail = p;
return;
}
if (p->prio_round > readyHead->prio_round) {
p->next = readyHead;
readyHead = p;
return;
}
PCB* prev = nullptr;
PCB* cur = readyHead;
while (cur != nullptr && cur->prio_round >= p->prio_round) {
prev = cur;
cur = cur->next;
}
prev->next = p;
p->next = cur;
if (cur == nullptr) readyTail = p;
}
// ---------- 轮转算法:插入就绪队列队尾 ----------
void INSERT2(PCB* p) {
p->next = nullptr;
if (readyHead == nullptr) {
readyHead = readyTail = p;
}
else {
readyTail->next = p;
readyTail = p;
}
}
// ---------- 调度就绪队列的第一个进程投入运行 ----------
void FIRSTIN() {
if (readyHead == nullptr) {
RUN = nullptr;
return;
}
RUN = readyHead;
readyHead = readyHead->next;
if (readyHead == nullptr) readyTail = nullptr;
RUN->next = nullptr;
RUN->state = 'R';
}
// ---------- 完成队列插入(按完成顺序) ----------
void finishInsert(PCB* p) {
p->next = nullptr;
p->state = 'F';
if (finishHead == nullptr) {
finishHead = finishTail = p;
}
else {
finishTail->next = p;
finishTail = p;
}
}
// ---------- 显示所有进程状态 ----------
void PRINT() {
cout << "\nname\tcputime\tneedtime\tpriority\tstate" << endl;
// 运行态
if (RUN != nullptr) {
cout << RUN->name << "\t" << RUN->cputime << "\t" << RUN->needtime << "\t\t"
<< RUN->prio_round << "\t\tR" << endl;
}
// 就绪态
PCB* cur = readyHead;
while (cur != nullptr) {
cout << cur->name << "\t" << cur->cputime << "\t" << cur->needtime << "\t\t"
<< cur->prio_round << "\t\tW" << endl;
cur = cur->next;
}
// 完成态
cur = finishHead;
while (cur != nullptr) {
cout << cur->name << "\t" << cur->cputime << "\t" << cur->needtime << "\t\t"
<< cur->prio_round << "\t\tF" << endl;
cur = cur->next;
}
cout << "--------------------------------------------------" << endl;
}
// ---------- 创建新进程 ----------
void CREATE(string name, int needtime) {
if (algorithm == 1) {
int prio = 50 - needtime;
PCB* p = new PCB(name, prio, needtime);
INSERT1(p);
}
else {
PCB* p = new PCB(name, 2, needtime);
INSERT2(p);
}
}
// ---------- 优先数调度算法 ----------
void PRISCH() {
cout << "\n========== 优先数调度算法 ==========" << endl;
cout << "初始状态:" << endl;
PRINT();
while (readyHead != nullptr || RUN != nullptr) {
if (RUN == nullptr) {
FIRSTIN();
PRINT(); // 显示刚调度的运行态
}
RUN->cputime += 1;
RUN->needtime -= 1;
RUN->prio_round -= 1;
if (RUN->needtime == 0) {
finishInsert(RUN);
RUN = nullptr;
}
else {
RUN->state = 'W';
INSERT1(RUN);
RUN = nullptr;
}
}
// 所有进程完成后,再显示一次,此时全部为 F
PRINT();
}
// ---------- 轮转调度算法 ----------
void ROUNDSCH() {
cout << "\n========== 循环轮转调度算法 ==========" << endl;
cout << "初始状态:" << endl;
PRINT();
while (readyHead != nullptr || RUN != nullptr) {
if (RUN == nullptr) {
FIRSTIN();
PRINT(); // 显示刚调度的运行态
}
RUN->cputime += 2;
RUN->needtime -= 2;
if (RUN->needtime <= 0) {
RUN->needtime = 0;
finishInsert(RUN);
RUN = nullptr;
}
else {
RUN->state = 'W';
INSERT2(RUN);
RUN = nullptr;
}
}
// 所有进程完成后,再显示一次,此时全部为 F
PRINT();
}
// ---------- 释放内存 ----------
void cleanup() {
auto deleteList = [](PCB* head) {
while (head) {
PCB* tmp = head;
head = head->next;
delete tmp;
}
};
deleteList(readyHead);
deleteList(finishHead);
if (RUN) delete RUN;
}
// ---------- 主程序 ----------
int main() {
cout << "进程调度模拟程序" << endl;
cout << "请选择算法:1 - 优先数调度算法 2 - 循环轮转调度算法" << endl;
int choice;
cin >> choice;
if (choice != 1 && choice != 2) {
cout << "输入错误,程序退出" << endl;
return 1;
}
algorithm = choice;
cout << "请依次输入5个进程的进程名 和 需要的时间片数(needtime):" << endl;
for (int i = 0; i < 5; ++i) {
string name;
int need;
cout << "第" << i + 1 << "个进程名: ";
cin >> name;
cout << "进程 " << name << " 的 needtime (正整数): ";
cin >> need;
while (need <= 0) {
cout << "needtime 应为正整数,请重新输入: ";
cin >> need;
}
CREATE(name, need);
}
if (algorithm == 1) {
PRISCH();
}
else {
ROUNDSCH();
}
cleanup();
return 0;
}
5.遇到的主要问题和解决方法
在实验中使用结构指针指向 PCB,且 PCB 内部又含有链表指针,操作时极易出现野指针导致程序崩溃。反复调试和检查指针赋值、链表插入与删除时的边界条件,并确保每次移动指针后均将原指针置空,最终消除了所有野指针,获得了正确结果。
四、实验结果
- 源代码行数:239
- 测试数据
优先数调度算法程序测试数据:
P1 2
P2 3
P3 4
P4 2
P5 4
循环轮转调度算法程序测试数据:
P1 3
P2 2
P3 4
P4 2
P5 1
浙公网安备 33010602011771号