C++ CPU调度程序

本文详细介绍了如何使用C++实现操作系统中的四种进程调度算法:非抢占式最短作业优先(sjf)、抢占式最短作业优先(psjf)、非抢占式优先级调度(pprio)和抢占式优先级调度(prio)。通过读取task.txt文件,模拟进程调度过程,输出调度顺序。代码中利用链表和标志位管理进程状态,确保正确调度。
摘要由CSDN通过智能技术生成

调度程序的实现包括几个部分:
1.导入task.txt文件,并将其字符串内容分割并以整数形式保存在结构体PCB的成员中。
2.四个调度算法函数,分别是sjf, psjf, pprio, prio。
sjf:最短作业优先调度(非抢占式)
psjf:最短作业优先调度(抢占式)
pprio:优先级调度(非抢占式)
prio:优先级调度(抢占式)

其中:四个调度算法函数大同小异,主要都利用链表(head,tail)和标志位(running、highest/shortest)来实现功能。running用来标志当前运行的进程是哪一个,highest用来标志当前ready队列中优先级最高的进程/shortest用来标志当前ready队列中剩余运行时间最短的进程。

时间由变量t表示,初始化为0,随着t每次自增1,程序将会进行几个判断:1. 遍历检查所有未开始的进程,看看是否有进程要进入ready队列;2.检查当前最高优先级进程/最短调度进程,并将其标志在highest/shortest;3.判断是否能进行调度(分为抢占和非抢占,抢占模式下仅检测标志位highest/shortest;而非抢占模式下需要检测标志位running和highest/shortest);4.判断当前进程是否运行完,如果运行完则将其状态置为terminal。
如果所有进程状态都为terminal,则跳出t自增的循环,并遍历链表,输出调度顺序。

typedef struct node {
	int procID;             /* 进程ID */
	int releaseTime;        /* 到达时间 */
	int priority;           /* 优先级 */
	int cpuTime;            /* 运行时间 */
	int executedTime;       /* 已运行时间 */
	int state;              /* 进程状态 -1是未开始,0是ready,1是running,2是terminal*/
	struct node * next;     /* 指向下一个进程指针 */
} PCB;

数据结构PCB,既用于存储从文件中读入的初始进程(procID唯一标识),又用于记录调度中的进程。(依据链表排序,输出procID和executedTime作为结果)

#include <iostream>
#include <string>
#include <fstream>

using namespace std;
typedef struct node {
	int procID;             /* 进程ID */
	int releaseTime;        /* 到达时间 */
	int priority;           /* 优先级 */
	int cpuTime;            /* 运行时间 */
	int executedTime;       /* 已运行时间 */
	int state;              /* 进程状态 -1是未开始,0是ready,1是running,2是terminal*/
	struct node * next;     /* 指向下一个进程指针 */
} PCB;
PCB pcb[10];
void sjf(int n)//非抢占式最短作业优先调度
{
	PCB *head = (PCB*)malloc(sizeof(PCB));
	int running = -1;//正在运行的进程
	int shortest = -1;//当前最短剩余时间进程
	for (int i = 0; i < n; i++)//初始化
	{
		pcb[i].state = -1;
		pcb[i].executedTime = 0;

	}
	for (int i = 0; i < n; i++)
	{
		if (pcb[i].releaseTime == 0)//把到达时间为0的进程i置为running状态
		{
			head->procID = pcb[i].procID;
			head->executedTime = 1;
			pcb[i].state = 1;
			pcb[i].executedTime = 1;
			//shortest = i;
			running = i;
			if (pcb[i].executedTime == pcb[i].cpuTime)
			{
				pcb[i].state = 2;
				running = -1;
			}
		}
	}
	PCB *tail = head;
	int t = 1;
	while (true)
	{
		int flag = 0;
		for (int i = 0; i < n; i++)
		{
			if (pcb[i].state != 2)
			{
				flag = 0;
				break;
			}
			flag = 1;
		}
		if (flag) break;//当所有进程的state都为2时,跳出大循环

		for (int i = 0; i < n; i++)//遍历检查所有未开始的进程,看看是否有进程要进入ready队列,同时检查当前最短作业进程
		{
			if (pcb[i].state == -1)
				if (pcb[i].releaseTime == t)
				{
					pcb[i].state = 0;
				}
		}
		for (int i = 0; i < n; i++)
		{
			if (pcb[i].state == 0)
			{
				if (shortest == -1)
					shortest = i;
				if (pcb[i].cpuTime - pcb[i].executedTime < pcb[shortest].cpuTime - pcb[shortest].executedTime)
					shortest = i;
			}
		}
		if (running == -1)//将当前最短作业进程置入running,由于是非抢占调度,加了running的锁
		{
			running = shortest;
			PCB *p = (PCB*)malloc(sizeof(PCB));
			p->procID = pcb[running].procID;
			p->executedTime = 0;
			pcb[running].state = 1;
			tail->next = p;
			tail = p;
			shortest = -1;
		}

		pcb[running].executedTime++;
		tail->executedTime++;

		if (pcb[running].executedTime == pcb[running].cpuTime)//判断当前进程是否运行完,如果运行完则移出running
		{
			pcb[running].state = 2;
			running = -1;
		}
		t++;
	}
	tail->next = nullptr;
	for (PCB *p = head; p != nullptr; p = p->next)
	{
		cout << p->procID << ":" << p->executedTime << endl;
	}
}
void psjf(int n)//抢占式最短作业优先调度
{
	PCB *head = (PCB*)malloc(sizeof(PCB));
	int running = -1;//正在运行的进程
	int shortest = -1;//当前最短剩余运行时间的进程
	for (int i = 0; i < n; i++)//初始化
	{
		pcb[i].state = -1;
		pcb[i].executedTime = 0;
	}

	for (int i = 0; i < n; i++)
	{
		if (pcb[i].releaseTime == 0)//把到达时间为0的进程i置为running状态
		{
			head->procID = pcb[i].procID;
			head->executedTime = 1;
			pcb[i].state = 1;
			pcb[i].executedTime = 1;
			shortest = i;
			running = i;
			if (pcb[i].executedTime == pcb[i].cpuTime)
			{
				pcb[i].state = 2;
				shortest = -1;
				running = -1;
			}
		}
	}
	PCB *tail = head;
	int t = 1;
	while (true)
	{
		int flag = 0;
		for (int i = 0; i < n; i++)
		{
			if (pcb[i].state != 2)
			{
				flag = 0;
				break;
			}
			flag = 1;
		}
		if (flag) break;//当所有进程的state都为2时,跳出大循环
		for (int i = 0; i < n; i++)//遍历检查所有未开始的进程,看看是否有进程要进入ready队列,同时检查当前最短作业进程
		{
			if (pcb[i].state == -1)
				if (pcb[i].releaseTime == t)
				{
					pcb[i].state = 0;
				}
		}
		for (int i = 0; i < n; i++)
		{
			if (pcb[i].state == 0)
			{
				if (shortest == -1)
					shortest = i;
				if (pcb[i].cpuTime - pcb[i].executedTime < pcb[shortest].cpuTime - pcb[shortest].executedTime)
					shortest = i;
			}
		}

		if (1)//将当前最短作业进程置入running,由于是抢占调度,没有关于running的锁
		{
			if (running == shortest)
				goto lable;
			pcb[running].state = 0;
			running = shortest;
			PCB *p = (PCB*)malloc(sizeof(PCB));
			p->procID = pcb[running].procID;
			p->executedTime = 0;
			pcb[running].state = 1;
			tail->next = p;
			tail = p;
		}
		lable:
		pcb[running].executedTime++;
		tail->executedTime++;
		if (pcb[running].executedTime == pcb[running].cpuTime)//判断当前进程是否运行完,如果运行完则移出running
		{
			pcb[running].state = 2;
			running = -1;
			shortest = -1;
		}
		t++;
	}
	tail->next = nullptr;
	for (PCB *p = head; p != nullptr; p = p->next)
	{
		cout << p->procID << ":" << p->executedTime << endl;
	}
}
void pprio(int n)//非抢占式优先级调度
{
	PCB *head = (PCB*)malloc(sizeof(PCB));
	int running = -1;//正在运行的进程
	int highest = -1;//当前最高优先级进程
	for (int i = 0; i < n; i++)//初始化
	{
		pcb[i].state = -1;
		pcb[i].executedTime = 0;
	}
	for (int i = 0; i < n; i++)
	{
		if (pcb[i].releaseTime == 0)//把到达时间为0的进程i置为running状态
		{
			head->procID = pcb[i].procID;
			head->executedTime = 1;
			pcb[i].state = 1;
			pcb[i].executedTime = 1;
			running = i;
			if (pcb[i].executedTime == pcb[i].cpuTime)
			{
				pcb[i].state = 2;
				running = -1;
			}
		}
	}
	PCB *tail = head;
	int t = 1;
	while (true)
	{
		int flag = 0;
		for (int i = 0; i < n; i++)
		{
			if (pcb[i].state != 2)
			{
				flag = 0;
				break;
			}
			flag = 1;
		}
		if (flag) break;//当所有进程的state都为2时,跳出大循环

		for (int i = 0; i < n; i++)//遍历检查所有未开始的进程,看看是否有进程要进入ready队列,同时检查当前最高优先级进程
		{
			if (pcb[i].state == -1)
				if (pcb[i].releaseTime == t)
				{
					pcb[i].state = 0;
				}

		}
		for (int i = 0; i < n; i++)
		{
			if (pcb[i].state == 0)
			{
				if (highest == -1)
					highest = i;
				if (pcb[i].priority > pcb[highest].priority)
					highest = i;
			}
		}
		if (running == -1)//将当前最高优先级的进程置入running,由于是非抢占调度,加了running的锁
		{
			running = highest;
			PCB *p = (PCB*)malloc(sizeof(PCB));
			p->procID = pcb[running].procID;
			p->executedTime = 0;
			pcb[running].state = 1;
			tail->next = p;
			tail = p;
			highest = -1;
		}

		pcb[running].executedTime++;
		tail->executedTime++;

		if (pcb[running].executedTime == pcb[running].cpuTime)//判断当前进程是否运行完,如果运行完则移出running
		{
			pcb[running].state = 2;
			running = -1;
		}
		t++;
	}
	tail->next = nullptr;
	for (PCB *p = head; p != nullptr; p = p->next)
	{
		cout << p->procID << ":" << p->executedTime << endl;
	}
}
void prio(int n)//抢占式优先级调度
{
	PCB *head = (PCB*)malloc(sizeof(PCB));
	int running = -1;//正在运行的进程
	int highest = -1;//当前最高优先级进程
	for (int i = 0; i < n; i++)//初始化
	{
		pcb[i].state = -1;
		pcb[i].executedTime = 0;
	}

	for (int i = 0; i < n; i++)
	{
		if (pcb[i].releaseTime == 0)//把到达时间为0的进程i置为running状态
		{
			head->procID = pcb[i].procID;
			head->executedTime = 1;
			pcb[i].state = 1;
			pcb[i].executedTime = 1;
			highest = i;
			running = i;
			if (pcb[i].executedTime == pcb[i].cpuTime)
			{
				pcb[i].state = 2;
				highest = -1;
				running = -1;
			}
		}
	}
	PCB *tail = head;
	int t = 1;
	while (true)
	{
		int flag = 0;
		for (int i = 0; i < n; i++)
		{
			if (pcb[i].state != 2) 
			{
				flag = 0;
				break;
			}
			flag = 1;
		}
		if (flag) break;//当所有进程的state都为2时,跳出大循环
		for (int i = 0; i < n; i++)//遍历检查所有未开始的进程,看看是否有进程要进入ready队列,同时检查当前最高优先级进程
		{
			if (pcb[i].state == -1)
				if (pcb[i].releaseTime == t)
				{
					pcb[i].state = 0;
				}
		}
		for (int i = 0; i < n; i++)
		{
			if (pcb[i].state == 0)
			{
				if (highest == -1)
					highest = i;
				if (pcb[i].priority > pcb[highest].priority)
					highest = i;
			}
		}

		if (1)//将当前最高优先级的进程置入running,由于是抢占调度,没有关于running的锁
		{
			if (running == highest)
				goto lable2;
			pcb[running].state = 0;
			running = highest;
			PCB *p = (PCB*)malloc(sizeof(PCB));
			p->procID = pcb[running].procID;
			p->executedTime = 0;
			pcb[running].state = 1;
			tail->next = p;
			tail = p;
		}
		lable2:
		pcb[running].executedTime++;
		tail->executedTime++;
		if (pcb[running].executedTime == pcb[running].cpuTime)//判断当前进程是否运行完,如果运行完则移出running
		{
			pcb[running].state = 2;
			running = -1;
			highest = -1;
		}
		t++;
	}
	tail->next = nullptr;
	for (PCB *p = head; p != nullptr; p = p->next)
	{
		cout << p->procID <<":"<< p->executedTime << endl;
	}
}

int main ()
{
//	PCB *p;
//	p_head = (PCB*)malloc(sizeof(PCB));
//	p = p_head;
	char str[20];
	char *s;
	int n = 0;
	ifstream in("task.txt");
	string line;
	if (in) // 有该文件
	{
		while (getline(in, line)) // line中不包括每行的换行符
		{
			if (n == 10)
			{
				cout << "进程数量溢出(大于10)" << endl;
				return -1;
			}

			int i;
			strcpy(str, line.c_str());
			s = strtok(str, " ");
			
			i = atoi(s);
			pcb[n].procID = i;//进程id
			s = strtok(NULL, " ");
			
			i = atoi(s);//到达时间
			pcb[n].releaseTime = i;
			s = strtok(NULL, " ");

			i = atoi(s);
			pcb[n].priority = i;//优先级
			s = strtok(NULL, " ");

			i = atoi(s);
			pcb[n].cpuTime = i;//运行时间

			n++;
			
		}
	}
	else // 没有该文件
	{
		cout << "no such file" << endl;
	}
	string alt[4]{ "sjf","psjf","pprio","prio" };
	cout << "选择调度算法sjf, psjf, pprio, prio" << endl;
	string select;
	cin >> select;
	if (select == alt[0])
		sjf(n);
	if (select == alt[1])
		psjf(n);
	if (select == alt[2])
		pprio(n);
	if (select == alt[3])
		prio(n);
	return 0;
}

对于文件task.txt ,进行非抢占式和抢占式最短作业优先调度:
sjf:
符合规律:
psjf:
符合规律:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值