Computer Operating System Experiment - Process Scheduling Simulation Algorithm

1. Purpose of the experiment

Process scheduling is the core content of processor management. This experiment requires writing a simulated process scheduler in a high-level language in order to deepen the understanding of concepts such as process control and process queues, and to experience and understand the specific implementation methods of the priority number algorithm and the time slice rotation algorithm.

2. Experimental requirements

1. Design the structure of the process control block PCB, usually including the following information:

Process name, process priority number (or number of rotation time slices), CPU time occupied by the process, time required for the process to complete, process status, current queue pointer, etc.

2. Write two scheduling algorithm programs:

Priority Number Scheduling Algorithm Program

Round Robin Scheduling Algorithm Program

3. Output the results as required.

3. Experimental process

Two scheduling algorithms are used to schedule the five processes respectively. Each process can have three states; execution state (RUN),

Ready state (READY, including waiting state) and completion state (FINISH), and assume that the initial state is the ready state.

 (1) The structure of the process control block is as follows:

 NAME - process identifier

 PRIO/ROUND——process priority number/the number of time slices for each process rotation (set to a constant 2)

 CPUTIME——The cumulative number of CPU time slices occupied by the process

 NEEDTIME - the number of time slices required for the process to complete

 STATE - process state

 NEXT - chain pointer

 Note:

 1. For the convenience of processing, the running time of the process in the program is calculated in units of time slices;

 2. The priority number or rotation time slices of each process, and the initial value of the process running time slices are all given by the user when the program is running.

(2) The ready state and waiting state of the process are linked list structures, and there are four pointers as follows:

 RUN - pointer to the currently running process

 READY - just need the queue head pointer

 TAIL - just need queue tail pointer

 FINISH - complete the queue head pointer

(3) Program Description

 1. In the priority number algorithm, the initial value of the process priority number is set to:

 50-NEEDTIME

Every time it is executed, the priority number is decreased by 1, the number of CPU time slices is increased by 1, and the number of time slices required by the process is decreased by 1. In the rotation method, a fixed time slice unit is used (two time slices are one unit), the process rotates once, the number of CPU time slices is increased by 2, and the number of time slices required by the process is reduced by 2, and the CPU is exited and queued to the ready queue end, waiting for the next dispatch.

 2. The module structure of the program is as follows:

 The whole program can be composed of the main program and the following seven processes:

 2

 (1) INSERT1—In the priority number algorithm, insert unfinished PCBs into the ready queue in order of priority;

 (2) INSERT2——In the rotation method, a time slice unit (2) will be executed, but the process has not yet been completed

PCB, inserted into the tail of the ready queue;

 (3) FIRSTIN - the first process in the scheduling ready queue is put into operation;

 (4) PRINT——Display the status and related information of all processes after each execution.

 (5) CREATE - create a new process and insert its PCB into the ready queue;

 (6) PRISCH——Scheduling processes according to the priority number algorithm;

 (7) ROUNDSCH——Schedule the process according to the time slice rotation method.

 The main program defines the PCB structure and other related variables.

code:

Main.cpp
#include<iostream>
#include<string>
using namespace std;
typedef struct node
{
	char name[20];           //进程名
	int prio;                      //进程优先级
	int round;                   //分配CPU的时间片
	int cputime;                //CPU执行时间
	int needtime;              //进程执行所需时间
	char state;                   //进程状态
	int count;                    //记录执行次数
	struct node *next;       //链表指针
}PCB;
int num;
//定义三个队列,就绪队列,执行队列,完成队列
PCB *ready = NULL;         //就绪队列
PCB *run = NULL;             //执行队列
PCB *finish = NULL;          //完成队列
//取得第一个就绪节点
void GetFirst()
{
	run = ready;
	if (ready != NULL)
	{
		run->state = 'R';
		ready = ready->next;
		run->next = NULL;
	}
}
//优先级输出队列
void Output1()
{
	PCB *p;
	p = ready;
	while (p != NULL)
	{
		cout << p->name << "\t" << p->prio << "\t" << p->cputime << "\t" << p->needtime << "\t " << p->state << "  \t  " << p->count << endl;
		p = p->next;
	}
	p = finish;
	while (p != NULL)
	{
		cout << p->name << "\t" << p->prio << "\t" << p->cputime << "\t" << p->needtime << "\t " << p->state << "  \t  " << p->count << endl;
		p = p->next;
	}
	p = run;
	while (p != NULL)
	{
		cout << p->name << "\t" << p->prio << "\t" << p->cputime << "\t" << p->needtime << "\t " << p->state << "  \t  " << p->count << endl;
		p = p->next;
	}
}
//轮转法输出队列
void Output2()
{
	PCB *p;
	p = ready;
	while (p != NULL)
	{
		cout << p->name << "\t" << p->round << "\t" << p->cputime << "\t" << p->needtime << "\t " << p->state << "\t  " << p->count << endl;
		p = p->next;
	}
	p = finish;
	while (p != NULL)
	{
		cout << p->name << "\t" << p->round << "\t" << p->cputime << "\t" << p->needtime << "\t " << p->state << "\t  " << p->count << endl;
		p = p->next;
	}
	p = run;
	while (p != NULL)
	{
		cout << p->name << "\t" << p->round << "\t" << p->cputime << "\t" << p->needtime << "\t " << p->state << "\t  " << p->count << endl;
		p = p->next;
	}
}
//创建优先级队列
//创建优先级队列,规定优先数越小,优先级越低 
void InsertPrio(PCB *in)
{
	PCB *fst, *nxt;
	fst = nxt = ready;
	if (ready == NULL)  //如果队列为空,则为第一个元素 
	{
		in->next = ready;
		ready = in;
	}
	else     //查到合适的位置进行插入 
	{
		if (in->prio >= fst->prio)  //比第一个还要大,则插入到队头
		{
			in->next = ready;
			ready = in;
		}
		else
		{
			while (fst->next != NULL)  //移动指针查找第一个比它小的元素的位置进行插入 
			{
				nxt = fst;
				fst = fst->next;
			}
			if (fst->next == NULL) //已经搜索到队尾,则其优先级数最小,将其插入到队尾即可 
			{
				in->next = fst->next;
				fst->next = in;
			}
			else     //插入到队列中
			{
				nxt = in;
				in->next = fst;
			}
		}
	}
}
//将进程插入到就绪队列尾部
void InsertTime(PCB *in)
{
	PCB *fst;
	fst = ready;
	if (ready == NULL)
	{
		in->next = ready;
		ready = in;
	}
	else
	{
		while (fst->next != NULL)
		{
			fst = fst->next;
		}
		in->next = fst->next;
		fst->next = in;
	}
}
//将进程插入到完成队列尾部
void InsertFinish(PCB *in)
{
	PCB *fst;
	fst = finish;
	if (finish == NULL)
	{
		in->next = finish;
		finish = in;
	}
	else
	{
		while (fst->next != NULL)
		{
			fst = fst->next;
		}
		in->next = fst->next;
		fst->next = in;
	}
}
//优先级调度输入函数 
void PrioCreate()
{
	PCB *tmp;
	int i;
	cout << "Enter the name and needtime:" << endl;
	for (i = 0; i < num; i++)
	{
		if ((tmp = (PCB *)malloc(sizeof(PCB))) == NULL)
		{
			cerr << "malloc" << endl;
			exit(1);
		}
		cin >> tmp->name;
		getchar();
		cin >> tmp->needtime;
		tmp->cputime = 0;
		tmp->state = 'W';
		tmp->prio = 50 - tmp->needtime;  //设置其优先级,需要的时间越多,优先级越低
		tmp->round = 0;
		tmp->count = 0;
		InsertPrio(tmp);      //按照优先级从高到低,插入到就绪队列 
	}
	cout << "进程名\t优先级\tcpu时间\t需要时间 进程状态 计数器" << endl;
}
//时间片输入函数 
void TimeCreate()
{
	PCB *tmp;
	int i;
	cout << "输入进程名字和进程时间片所需时间:" << endl;
	for (i = 0; i < num; i++)
	{
		if ((tmp = (PCB *)malloc(sizeof(PCB))) == NULL)
		{
			cerr << "malloc" << endl;
			exit(1);
		}
		cin >> tmp->name;
		getchar();
		cin >> tmp->needtime;
		tmp->cputime = 0;
		tmp->state = 'W';
		tmp->prio = 0;
		tmp->round = 2;
		tmp->count = 0;
		InsertTime(tmp);
	}
	cout << "进程名\t轮数\tCPU时间\t需要时间 进程状态 计数器" << endl;
}
//按照优先级调度,每次执行一个时间片
void Priority()
{
	int flag = 1;
	GetFirst();
	while (run != NULL)
	{
		Output1();
		while (flag)
		{
			run->prio -= 3; //优先级减去三 
			run->cputime++; //CPU时间片加一 
			run->needtime--;//进程执行完成的剩余时间减一 
			if (run->needtime == 0)//如果进程执行完毕,将进程状态置为F,将其插入到完成队列 
			{
				run->state = 'F';
				run->count++;
				InsertFinish(run);
				flag = 0;
			}
			else   //将进程状态置为W,入就绪队列
			{
				run->state = 'W';
				run->count++; //进程执行的次数加一
				InsertTime(run);
				flag = 0;
			}
		}
		flag = 1;
		GetFirst();    //继续取就绪队列队头进程进入执行队列 
	}
}
void RoundRun()    //时间片轮转调度算法
{
	int flag = 1;
	GetFirst();
	while (run != NULL)
	{
		Output2();
		while (flag)
		{
			run->count++;
			run->cputime++;
			run->needtime--;
			if (run->needtime == 0) //进程执行完毕 
			{
				run->state = 'F';
				InsertFinish(run);
				flag = 0;
			}
			else if (run->count == run->round)//时间片用完 
			{
				run->state = 'W';
				run->count = 0;   //计数器清零,为下次做准备 
				InsertTime(run);
				flag = 0;
			}
		}
		flag = 1;
		GetFirst();
	}
}
int main(void)
{
	int n;
	cout << "输入进程个数:" << endl;
	cin >> num;
	getchar();
	cout << "-----------------进程调度算法模拟----------------------" << endl;
	cout << "                   1、优先级调度算法" << endl;
	cout << "                   2、循环轮转调度算法  " << endl;
	cout << "-------------------------------------------------------" << endl;
	cout << "输入选择序号:" << endl;
	cin >> n;
	switch (n)
	{
	case 1:
		cout << "优先级调度:" << endl;
		PrioCreate();
		Priority();
		Output1();
		break;
	case 2:
		cout << "循环轮转算法:" << endl;
		TimeCreate();
		RoundRun();
		Output2();
		break;
	case 0:
		exit(1);
		break;
	default:
		cout << "Enter error!" << endl;
		break;
	}
	cout << endl;
	return 0;
}

Guess you like

Origin blog.csdn.net/y0205yang/article/details/130207719