实验目的:在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就绪状态进程 个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。本实验模拟在 单处理器情况下处理器调度,帮助学生加深了解处理器调度的工作。
题目:设计一个按优先数调度算法实现处理器调度的进程。
注:代码网上较多,我适当修改以符合我们老师的题目要求。
编程语言:C/C++?
编译环境:Vs code
运行截图:
代码如下:?
// 操作系统实验一:按优先数调度算法实现处理器调度的进程。
// 优先数越大,优先级越高!
// 编译环境: Vs code
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <ctime>
#include <string>
#include <stdlib.h>
using namespace std;
// 定义进程控制块
struct PCB
{
string name; // 进程名
PCB *next; // 链接指针
int arrive_time = 0; // 到达时间
int priority = 0; // 进程的优先级
int run_time = 0; // 预计运行时间
string status; // 进程状态
} head;
PCB *runing = new PCB; // 指向正在运行的进程的指针
PCB *runing_last = new PCB; //指向正在运行的进程的上一个进程的指针
int currentTime = 0; // 系统时间
PCB *init()
{ //初始化创建进程列表
PCB *head = new PCB;
PCB *end, *normal;
int processNumber; // 进程的数目
srand((unsigned)time(NULL));
processNumber = 5;
end = head;
end->next = NULL;
int i = 1;
while (processNumber)
{
normal = new PCB;
normal->name = 'P' + std::to_string(i); // 初始化进程名
normal->arrive_time = rand() % 10 + 1; // 进程到达时间随机初始化为1-10
normal->priority = rand() % 5 + 10; // 进程优先级随机初始化为10-15
normal->run_time = rand() % 10 + 1; // 进程预计运行时间随机初始化为1-10
normal->status = "Ready"; // 设置进程状态
end->next = normal; // 将新的进程放在尾节点的进程后面
end = normal; // 新的进程成为尾进程
processNumber--; // 自减,用来计数
i++; // 用来起名,保证每一个进程名不同
}
end->next = NULL; // 创建完成之后,将尾节点的下一个节点置为空
PCB *p;
p = head; // 将头节点传递给p指针
cout << "初始进程队列:" << endl;
cout << "进程名" << '\t' << "到达时间" << '\t' << "优先数" << '\t' << '\t' << "需要运行时间" << '\t' << "进程状态" << endl;
while (p->next != NULL)
{ // 输出初始化生成的进程数据
p = p->next;
cout << p->name << '\t' << ' ' << p->arrive_time << '\t' << '\t' << p->priority << '\t' << '\t' << p->run_time << '\t' << '\t' << p->status << endl;
}
cout << "--------------------------This is the dividing line.---------------------------" << endl;
return head; // 返回头指针
}
PCB *Sort(PCB *head) // 按priority进行排序
{
int i, count = 0, num; // count记录链表结点的个数,num进行内层循环,
PCB *p, *q, *tail; //创建三个指针,进行冒泡排序
p = head;
while (p->next != NULL) //计算出结点的个数
{
count++; //注释①
p = p->next;
}
for (i = 0; i < count - 1; i++) //外层循环,跟数组冒泡排序一样
{
num = count - i - 1; //记录内层循环需要的次数,跟数组冒泡排序一样,
q = head->next; //令q指向第一个结点
p = q->next; //令p指向后一个结点
tail = head; //让tail始终指向q前一个结点,方便交换,也方便与进行下一步操作
while (num--) //内层循环 次数跟数组冒泡排序一样
{
if (q->priority < p->priority) //如果该结点的值大于后一个结点,则交换
{
q->next = p->next;
p->next = q;
tail->next = p;
}
tail = tail->next;
q = tail->next;
p = q->next;
}
}
return head;
}
void showProgressCondition(PCB *head)
{
PCB *p = head; // 将头指针传给p指针
if (p->next == NULL)
{ // p指针指向的下一个节点为空则代表链表为空,
cout << "就绪队列中已经没有进程了!";
}
else
{
cout << "运行完成后就绪队列中的情况:" << endl;
cout << "进程名" << '\t' << "到达时间" << '\t' << "优先数" << '\t' << '\t' << "需要运行时间" << '\t' << "进程状态" << endl;
while (p->next != NULL)
{
p = p->next;
if (p->arrive_time <= currentTime)
cout << p->name << '\t' << ' ' << p->arrive_time << '\t' << '\t' << p->priority << '\t' << '\t' << p->run_time << '\t' << '\t' << p->status << endl;
}
cout << "--------------------------This is the dividing line.---------------------------" << endl;
}
}
int priorityScheduling(PCB *head)
{
currentTime++; // currentTime自增,代表系统时间加一
head = Sort(head); // 排序
for (PCB *p = head->next, *q = head; p; q = p, p = p->next) // 选取队列里第一个已到达的进程
{
if (p->arrive_time <= currentTime)
{
runing = p;
runing_last = q;
break;
}
}
cout << "当前的时间为:" << currentTime << endl; //输出当前系统时间
if (runing != NULL)
{ // 如果当前运行进程指针不为空,则代表就绪列表中有进程,可以进行输出
cout << "当前运行的进程为:" << runing->name << "进程!" << endl;
runing->priority--; // 优先级数减一
runing->run_time--; // 预计运行时间减一
runing->status = "Running"; // 状态变为运行态
if (runing->run_time == 0)
{
// 调用函数,输出当前就绪队列中的情况
cout << "进程" << runing->name << "已经运行完毕" << endl;
runing->status = "End"; // 置进程的状态为完成态
showProgressCondition(head);
runing_last->next = runing->next; //从链表中删除该节点
delete runing; //释放内存
runing = NULL; // 节点删除之后,把当前最高优先级指针置为空
}
else
{
showProgressCondition(head);
runing->status = "Ready"; // 如果没运行完成,则把进程的状态切换回就绪态,
}
}
else
{ // 就绪队列中没有进程
cout << "当前就绪列表无进程!" << endl;
}
return 0; //返回0
}
int main()
{
int choose = 0;
string select;
bool runForAll = false;
runing = NULL; // 一开始把当前最高优先级指针置空
PCB *head; // 声明指针
head = init(); // 创建链表,用指针接受返回的头指针
while (head->next != NULL)
{ // 利用循环,一直到链表中的进程全部退出链表才会结束循环
priorityScheduling(head); // 调用函数,进行优先级调度
if (!runForAll)
{
cout << "请输入数字或字母以继续,或输入“exit”退出,输入“all”直接运行结束。" << endl;
cin >> select;
if (select == "exit")
break;
else if (select == "all")
runForAll = true;
}
}
return 0;
}
|