[Operating system] The process scheduling algorithm with the highest response ratio priority - C language (with code)

This article will introduce the process scheduling algorithm with the highest response ratio priority, and implement it according to the following requirements:

The code is at the end of the article

  • The name of each process is entered by the user, and the required running time
  • For each round of scheduling, calculate the response ratio of each process, R = (W+S)/S=1+W/S, W: waiting time, S: expected execution time
  • The ready process with the highest response ratio per dispatch
  • If the "required running time" of a process == "elapsed running time", set its status to "end", and exit the queue to run the program, display the name of the process scheduled to run each time it is scheduled, and the control block of each process dynamic process

1. What is the process scheduling algorithm with the highest response ratio priority

High Response Ratio Priority Scheduling           Algorithm ( Highest Response Ratio Next ) is an algorithm for allocating the response ratio of the CPU  central controllerHRRN is a compromise algorithm between FCFS (first come, first served algorithm) and SJF (short job first algorithm), which considers both job waiting time and job running time, and takes care of short jobs without making long job waiting time too long Long, improved scheduling performance. This algorithm allows long jobs with a long waiting time to be executed, but the response ratio must be estimated each time they are scheduled, which consumes more CPU time.

        The response ratio is calculated as follows:

Response ratio = (waiting time + required service time) / required service time, that is, RR=(w+s)/s=1+w/s, so the response ratio must be greater than or equal to 1, where, W: waiting time, S: Estimated execution time.

Second, the elements that must be included in the process pcb

The process pcb must contain the following elements, which can be further expanded as required:

pcb

process id

The time the process takes to run
process wait time
Process Response Ratio
process status

3. Example display

The process queue is as follows:

Process services are as follows:

 The order of execution is as follows:

A——>B——>C——>E——>D

4. Realization

4.1. Data structure

        In the code implementation, a chain structure is used, so that each process is connected through a pointer, which makes it convenient to query the process with the highest response ratio, and also makes it more convenient to add processes.

4.2. Algorithm Core

        There are two cores of this algorithm. The first one is the update of the response ratio of the process queue. Since the process scheduling with the highest response ratio priority is non-preemptive, after each process is executed, the waiting time of the processes in the process queue is longer. Make response adjustments and recalculate response ratios. The second is to find the process with the highest response ratio in the process queue, and there are two ways to find the process with the highest response ratio. The first is to traverse the response ratio of all processes in the process queue to find the largest one. The time complexity of this method is O(n); the second is to sort all processes, the time complexity of this method is at least n*logn. In the author's implementation code is the first method used.

4.3, code implementation

#include <stdio.h>
#include <stdlib.h>

//最高响应比
typedef struct pcb {
	int pid;
	char state;//E为完成,R为正在运行,W为在就绪队列
	int total_time;//需要的时间
	
	double waittime;//等待时间
	double response;//响应比
	int cputime;//已经执行的时间
	int mark;//标志位,用来表示正在执行的进程,1为在cpu,0为不在cpu
	struct pcb* next;
}*proc;


//初始化进程,需要用户输入进程id和需要cpu的时间
proc init_pcb(struct pcb* head,struct pcb* tail,int mark,int* proc_num) {
	int i;
	//防止进程id重复
	//static int pcb_id[20] = { 0 };
	//static int pcb_id_index = 0;
	int numofpcb;
	proc p, tmp;
	printf("please input the number of process:\n");
	scanf("%d", &numofpcb);
	printf("there are %d processes,please input pcb info:\n", numofpcb);
	p = (proc)malloc(sizeof(struct pcb));
	printf("process id:");
	scanf("%d", &p->pid);
	//do {
	  //printf("process id:");
	  //scanf("%d", &p->pid);
	//	if (pcb_id_index != 0) {
	//		for (int i = 0; i < pcb_id_index; i++) {
	//			if (p->pid == pcb_id[i]) {
	//				printf("process id exist!\n");
	//				break;
	//			}
	//		}
	//	}
	//} while (1);
	//pcb_id[pcb_id_index] = p->pid;
	//pcb_id_index++;
	p->response = 1.0;
	printf("cputime required:");
	scanf("%d", &p->total_time);
	p->state = 'W';
	p->cputime = 0;
	p->mark = mark;
	p->waittime = 0;
	
	head = p;

	for (i = numofpcb; i > 1; i--) {
		tmp = p;
		p = (proc)malloc(sizeof(struct pcb));
		printf("process id:");
		scanf("%d", &p->pid);
		p->response = 1.0;
		printf("cputime required:");
		scanf("%d", &p->total_time);
		p->state = 'W';
		p->cputime = 0;
		p->mark = 0;
		p->waittime = 0;
		
		tmp->next = p;
	}
	tail = p;
	p->next = head;
	*proc_num = (*proc_num) + numofpcb;
	return tail;
}


//找到响应比最大的进程,并返回该进程
proc find_max_response(proc node, struct pcb* head,int* proc_num) {
	double maxresponse;
	proc p = head;
	proc tmp = p, res = p;
	
	//在进程队列中找到响应比最大的进程
	tmp = node;
	proc find = head;
	maxresponse = find->response;
	for (int i = 0; i < *proc_num; i++) {
		if (find->response > maxresponse) {
			res = find;
			tmp->mark = 0;
			res->mark = 1;
			tmp = res;
			maxresponse = res->response;
		}
		find = find->next;
	}
	return res;
}



//调整所有进程的响应,正在执行的进程响应不变,重新计算其他进程的响应比
//因为为抢占式的,平且进程队列会将完成的进程从进程队列删除,所以在进程队列中的进程全是需要调整响应比的
void set_all_process_response(proc head,int* proc_num,proc ntodo) {
	proc tmp = head;
	for (int i = 0; i < *proc_num; i++)
	{
		tmp->waittime = tmp->waittime + ntodo->total_time;
		tmp->response = 1 + tmp->waittime / tmp->total_time;
		tmp = tmp->next;
	}
}

//打印进程的pid、waittime、req_time、response
void display(struct pcb* head,int* proc_num) {
	int i;
	proc p = head;
	printf("pid\twait\treq_time\tresponse\n");
	for (i = 0; i < *proc_num; i++) {
		printf("%d\t%.0lf\t%d\t\t%lf\n", p->pid, p->waittime, p->total_time, p->response);
		p = p->next;
	}
	printf("----------------------------------\n");
}

//删除已经执行完成的进程,并返回进程队列的尾指针
proc delete_finished_pro(proc node, struct pcb* head, struct pcb* tail,int* proc_num) {
	if (head == tail) {
		return NULL;
	}
	proc pre = tail;

	for (int i = 0; i < *proc_num; i++) {
		if (pre->next->pid == node->pid) {
			pre->next = node->next;
			tail = pre;
			head = pre->next;
			break;
		}
	}
	//调整进程数量
	(*proc_num)--;
	return tail;
}

//插入新进程,使用init_pcb()函数完成该功能,并将新进程插入到原进程队列
//中得到新进程队列,并返回新进程队列的尾指针
proc insert_proc(int* insertnum,proc head,proc tail,int* proc_num) {
	proc inhead = NULL, intail = NULL;
	intail = init_pcb(inhead, intail, 0,proc_num);
	inhead = intail->next;
	proc tmp = inhead;

	tail->next = inhead;
	tail = intail;
	tail->next = head;
	//*proc_num = (*proc_num) + *insertnum;
	return tail;
}

//用户选择是否插入新进程,返回进程队列的尾指针
proc judg_insert_proc(int* insertnum,proc head,proc tail,int* proc_num) {
	int choice = 0;
	/*proc intail;*/
	printf("insert new processes or not,please input number(1 yes,0 no):");
	scanf("%d", &choice);
	if (choice == 1) {
		if (head == NULL) {
			tail = init_pcb(head, tail, 1, proc_num);
			head = tail->next;
			return tail;
		}
		tail = insert_proc(insertnum, head, tail,proc_num);
	}
	return tail;
}

//基于动态优先级的进程调度算法,找出优先级最大的进程执行,每一个cpu时间片,调整一次
//所有进程的优先级,再重新寻找优先级最高的进程
void priority(struct pcb* head, struct pcb* tail,int* proc_num) {
	int* insertnum = (int*)malloc(sizeof(int));
	proc intail, inhead;
	*insertnum = 0;
	int i, round;
	double maxlevel;
	round = 1;
	proc p = head;
	proc t = tail;
	proc ntodo, nowmark;
	nowmark = p;
	ntodo = p;//response最大的,马上要做的
	maxlevel = p->response;
	for (i = 0; i < *proc_num; i++) {
		p = p->next;
		if (p->response > maxlevel) {
			ntodo = p;
			nowmark->mark = 0;
			ntodo->mark = 1;
			nowmark = ntodo;
			maxlevel = ntodo->response;
		}
	}
	while (ntodo->total_time > ntodo->cputime)
	{
		*insertnum = 0;
		printf("\n* Round %d, Process %d is running\n", round, ntodo->pid);
		round = round + ntodo->total_time;
		ntodo->state = 'E';
		
		set_all_process_response(head,proc_num,ntodo);
		tail = delete_finished_pro(ntodo, head, tail, proc_num);
		if (tail == NULL) {
			head = NULL;
		}
		else
		{
			head = tail->next;
			display(head, proc_num);
		}
		
		printf("\n▲ process %d is finished\n", ntodo->pid);

		if (head == tail&&head==NULL) {
			
			tail = judg_insert_proc(insertnum, head, tail, proc_num);
			if (tail == NULL) {
				printf("over!!!\n");
				return;
			}
			head = tail->next;
		}
		else
		{
			tail= judg_insert_proc(insertnum, head, tail, proc_num);
			head = tail->next;
		}
		

		ntodo = find_max_response(ntodo,head, proc_num);
	}
}

int main() {
	int* proc_num = (int*)malloc(sizeof(int));
	*proc_num = 0;
	int mark = 1, inmark = 0;
	struct pcb* head = NULL, * tail = NULL;
	tail = init_pcb(head, tail,mark,proc_num);
	head = tail->next;
	display(head,proc_num);
	priority(head,tail,proc_num);
	return 0;
}

Guess you like

Origin blog.csdn.net/peng_lv/article/details/127814730