【操作系统】基于动态优先级的进程调度算法-C语言实现(有代码)

这篇具有很好参考价值的文章主要介绍了【操作系统】基于动态优先级的进程调度算法-C语言实现(有代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文章将会介绍如何编写动态优先级的进程调度算法,并使用从语言实现。

一、什么是动态优先级的调度算法

       进程运行一个时间片后,如果进程已占用 CPU时间已达到所需要的运行时间,则撤消该进程;如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。所以在在该程序中每一个时间片后都需要调整一次程序的优先级,并且在所有的进程中找到优先级最大的进程,而实现在进程中找到优先级最大的进程有两种方式:一种是遍历所有的进程找到所有的进程;第二种是根据优先级对进程进行排序。

二、进程pcb中必须包含的元素

     进程pcb必须包含以下五个元素,可以按需求增加其他元素:

pcb
进程名
优先级
需要运行的时间
已经运行的时间
状态

三、流程图

动态优先级调度算法c语言,操作系统,算法,c语言

四、例题展示

四个进程A、B、C、D,在同一时刻到达,个程序的优先级如下图所示:

进程 到达时间 开始时间 需要运行的时间 优先级 完成时间
A 0 6 2 1 8
B 0 1 2 3 4
C 0 5 2 2 7
D 0 0 2 4 3

第一个时间片:

此时D的优先级最高,应该执行,所以D的开始时间为0,时间片结束,优先级减一,优先级变为3

第二个时间片:

此时B和D的优先级最高,都为3,如果按顺序来执行,就是B执行,所以B的开始为1,时间片结束,优先级减一,优先级变为2

第三个时间片:

此时D的优先级最高,时间片结束,优先级减一,优先级变为2,运行结束

第四个时间片:

此时B、C的优先级最高,都为2,按顺序来,B执行,时间片结束,优先级减一,优先级变为1,运行结束

第五个时间片:

此时C的优先级最高,为2,C执行,所以C的开始时间为5,时间片结束,优先级减一,优先级变为1

第六个时间片:

A、C优先级都为1,A执行,所以A的开始时间为6,时间片结束,优先级减一,优先级变为0

第七个时间片:

C的优先级最高,C执行,时间片结束,优先级减一,优先级变为0,运行结束

第八个时间片:

A运行,并允许结束

五、具体实现

5.1、数据结构

       采用链式结构,即一个进程可以指向下一个进程,这样方便增加进程的个数,同时如果是使用遍历法求最大优先级的进程,在链式结构下也是十分方便实现的。

5.2、如何得到进程队列中优先级最大的进程

        按照之前说的找到优先级最大的进程有两种方法,一是遍历所有的进程,二是根据进程优先级对所有的进程进行排序。第一种方法的操作简单且复杂度为O(n),第二种方法操作较为复杂且复杂度为n*logn。作者的实现是使用的第一种。

5.3、代码如下文章来源地址https://www.toymoban.com/news/detail-735914.html

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

//动态优先级
typedef struct pcb {
	int pid;
	char state;//E为完成,R为正在运行,W为在就绪队列
	int total_time;//需要的时间
	int level;//优先级
	int cputime;//已经执行的时间
	int mark;//标志位,用来表示正在执行的进程,1为在cpu,0为不在cpu
	struct pcb* next;
}*proc;


//初始化进程,返回进程队列的尾指针
proc init_pcb(struct pcb* head,struct pcb* tail,int mark,int* proc_num) {
	int i;
	//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++;
	printf("the processes level:");
	scanf("%d", &p->level);
	printf("cputime required:");
	scanf("%d", &p->total_time);
	p->state = 'W';
	p->cputime = 0;
	p->mark = mark;
	head = p;

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


//找到进程队列中优先级最高的进程,并将该进程指针返回
proc find_max_level(proc node, struct pcb* head,int* proc_num) {
	int maxlevel;
	proc p = head;
	proc tmp = p, res = p;
	tmp = node;
	//从头指针开始找优先级最大的进程
	maxlevel = head->level;
	proc find = head;
	for (int i = 0; i < *proc_num; i++) {
		//if (find->state == 'E') {
		//	find = find->next;
		//	continue;
		//}
		if (find->level >= maxlevel) {
			res = find;
			tmp->mark = 0;
			res->mark = 1;
			tmp = res;
			maxlevel = res->level;
		}
		find = find->next;
	}
	return res;
}



//调整所有进程的优先级,正在执行的优先级减一
void set_all_process_level(proc nowrunning,int* proc_num) {
	proc temp = nowrunning;
	nowrunning->level--;
}

//打印进程的id、cpu_time、req_time、level
void display(struct pcb* head,int* proc_num) {
	int i;
	proc p = head;
	printf("pid cpu_time req_time level\n");
	for (i = 0; i < *proc_num; i++) {
		printf("%d\t%d\t%d\t%d\n", p->pid, p->cputime, p->total_time, p->level);
		p = p->next;
	}
	printf("----------------------------------\n");
}

//删除进程队列中已经完成的进程
proc delete_finished_pro(proc node, struct pcb* head, struct pcb* tail,int* proc_num) {
	proc pre = tail;
	//通过id来识别已经完成的队列
	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) {//进程队列中没有进程了,直接使用init_pcb()函数
			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));
	*insertnum = 0;
	int round = 1, i, maxlevel;
	proc p = head;
	proc t = tail;
	proc ntodo, nowmark;
	nowmark = p;
	ntodo = p;//leve最大的,马上要做的
	maxlevel = p->level;
	for (i = 0; i < *proc_num; i++) {
		p = p->next;
		if (p->level > maxlevel) {
			ntodo = p;
			nowmark->mark = 0;
			ntodo->mark = 1;
			nowmark = ntodo;
			maxlevel = ntodo->level;
		}
	}
	while (ntodo->total_time > ntodo->cputime)
	{
		*insertnum = 0;
		printf("\n* Round %d, Process %d is running\n", round, ntodo->pid);
		round++;
		ntodo->cputime++;
		if (ntodo->total_time == ntodo->cputime) {
			ntodo->state = 'E';
			tail = delete_finished_pro(ntodo, head, tail, proc_num);
			head = tail->next;
			set_all_process_level(ntodo,proc_num);
			display(head,proc_num);
			printf("\n▲ process %d is finished\n", ntodo->pid);

			if (head == tail) {
				head = NULL, tail = NULL;
			}

			
			tail = judg_insert_proc(insertnum, head, tail,proc_num);
			if (tail == NULL) {
				printf("over!!!\n");
				return;
			}
			head = tail->next;
			display(head, proc_num);
			ntodo = find_max_level(ntodo,head, proc_num);
			continue;
		}
		set_all_process_level(ntodo, proc_num);//重新调整level
		
		display(head, proc_num);
		tail = judg_insert_proc(insertnum, head, tail, proc_num);
		tail->next = head;
		ntodo = find_max_level(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;
}

到了这里,关于【操作系统】基于动态优先级的进程调度算法-C语言实现(有代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 不同语言操作符的优先级

    不同语言操作符的优先级

    看到标题,可能会心生疑惑: 这么基础且重要的操作,不同语言不应该是一致的吗? 并不一定,比如对于右移运算和加法运算,Go就与其他多数语言表现得不一致: Go: Java: C/C++: nodejs: python: php: 本文由 mdnice 多平台发布

    2024年02月14日
    浏览(20)
  • Allegro如何设置铜皮避让的优先级操作指导

    Allegro如何设置铜皮避让的优先级操作指导

    Allegro 如何设置铜皮避让的优先级操作指导   在用Allegro进行PCB设计的时候,时常需要使用动态铜皮进行设计,当两块动态铜皮存在交集的时候,避让就会存在一个优先级,如下图 上方的铜皮避让调了下方的铜皮,上方的铜皮被避让了 如何调整让下方的铜皮避让上方的铜皮,

    2024年02月15日
    浏览(8)
  • C语言操作符详解+运算符优先级表格

    C语言操作符详解+运算符优先级表格

       目录  前言 一、操作符是什么? 二、操作符的分类 三、算术操作符 四、逻辑操作符 五、比较操作符 六、位操作符 七、赋值操作符 八、其他操作符  九、运算符优先级表格 总结 在编写程序时,最常用到的就是操作符,本文将详细的介绍我们在编写程序时需要用到的操

    2024年01月18日
    浏览(16)
  • c语言-操作符详解(含优先级与结合性)

    c语言-操作符详解(含优先级与结合性)

    操作数: 操作数是用于运算的数字或者表达式 如: 1 . 1+1 2.(a+b)*3 操作符 操作符,也称运算符。是对数据进行操作处理的符号。 操作符有很多,常见操作符有:单目操作符、算数操作符、移位操作符、位操作符、赋值操作符、关系操作符、逻辑操作符、条件操作符、逗号表达

    2024年02月05日
    浏览(7)
  • 【进程调度】基于优先级的轮转调度C++实现算法

    【进程调度】基于优先级的轮转调度C++实现算法

    在计算机科学领域, 进程调度是操作系统中一个关键的组成部分,它负责协调系统中各个进程的执行顺序,以最大程度地提高系统资源利用率 。在这篇博客中,将深入探讨基于优先级的轮转调度算法,该算法结合了进程的 优先级 和 时间片轮转 的思想,以实现高效的任务执

    2024年01月20日
    浏览(11)
  • 【看表情包学Linux】进程优先级 | 查看系统进程 | 优先级修改 | 进程的切换 | 竞争性与独立性 | 并行并发的概念 | 环境变量

    【看表情包学Linux】进程优先级 | 查看系统进程 | 优先级修改 | 进程的切换 | 竞争性与独立性 | 并行并发的概念 | 环境变量

       🤣  爆笑 教程  👉 《看表情包学Linux》👈   猛戳订阅     🔥 ​ 💭 写在前面: 我们先讲解进程的优先级,探讨为什么会存在优先级,以及如何查看系统进程、进程优先级的修改。然后讲解进程的切换,首次介绍进程的竞争性、独立性,以及并行和并发的概念,在通

    2024年01月19日
    浏览(11)
  • c语言[]优先级大于*优先级

    c语言[]优先级大于*优先级

    本博文源于笔者正在学习的c语言[]优先级大于*优先级.在定义二维数组时,a+1与[]号结合后,谁的优先级更高,是本博文探讨的话题 想要看看*与[]谁的优先级更高 通过代码发现[]优先级比*号要高(a+1)[1]等价于a+2再取*号就是9了,在第二个pirintf代码中,等价于a[1][1] =6,第三个

    2024年01月20日
    浏览(19)
  • 【C语言】表达式求值相关问题汇总—>隐式类型转换(整型提升)、算数转换与操作符优先级汇总(收藏查阅)

    【C语言】表达式求值相关问题汇总—>隐式类型转换(整型提升)、算数转换与操作符优先级汇总(收藏查阅)

     👀 樊梓慕: 个人主页   🎥 个人专栏: 《C语言》《数据结构》《蓝桥杯试题》 🌝 每一个不曾起舞的日子,都是对生命的辜负。 目录 前言: 一、隐式类型转换 (一)整型提升的意义 (二)如何进行整型提升呢? 二、算数转换 三、操作符的属性 (一)操作符优先级汇

    2024年02月16日
    浏览(13)
  • NVIC 简介、抢占优先级和响应优先级

    NVIC 简介、抢占优先级和响应优先级

    NVIC 是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。 如果医院只有医生的话,当看病的人很多时,医生就得安排一下先看谁,后看谁,如果有紧急的病人,那还得让紧急的病人最先来,这个安排先后次序的任务很繁琐,

    2024年02月05日
    浏览(17)
  • 中断处理优先级和中断响应优先级的区别

    中断处理优先级和中断响应优先级的区别

      中断响应优先级是针对同时到达的中断请求先处理谁的规定。比如A、B同时向CPU发出中断请求,而中断响应优先级是AB,那么CPU就会先处理A,再处理B。   如下图:   中断处理优先级是解决中断嵌套情况下优先处理谁的问题。比如A、B两个中断的中断处理优先级是BA,

    2024年02月11日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包