模拟进程_2

模拟进程_2

害,我又来了,对昨天发布的博客中程序的一些地方做了改善。写这个也没有别的目的,就是想记录一下自己在大学的一些学习成果。可能以后再看会觉得很搞笑,很低智。但这作为学习阶段的一个记录,我觉得还是不错的,至少现阶段觉得不错。。。。哈!

一、运行结果

初始设置:
在这里插入图片描述
菜单页面:
在这里插入图片描述
运行结果:
在这里插入图片描述

在这里插入图片描述

二、源代码

代码如下:

 #include<stdio.h>
 #include<stdlib.h>
 #include<conio.h>
 struct pcb{
 	char name;//外部名称 
 	int pid;//内部编号 
 	int s;//状态 -1空闲 0就绪 1运行 
 	int job;//工作量
	int jobn; 
 	int cur;//尾 
 	int ts;//开始时间 
	int tf; //结束时间 
 };
 
// 初始化数组 
 void init(struct pcb *pcb,int n){
 	int i=0;
 	while(i<(n-1)){
 		pcb[i].s=-1;//-1表示空闲态 
 		pcb[i].job=999999;
 		pcb[i].pid=i;//赋予内部值 
 		pcb[i].cur=i+1;
 		//printf("--%d--",pcb[i].pid);//检错 
 		//printf("*%d*",pcb[i].cur);//检错 
		i++;
	 }
	 pcb[i].pid=i;//最后一个pcb块赋予内部值 
	 pcb[i].job=99999;
	 pcb[i].cur=-999;
 }
 
// 测试空值函数
int space_number(struct pcb *pcb){
	int i,j;
	i=0;
	j=0;
	while(pcb[i].cur>=0){
	//printf("%d -> ",pcb[i].pid);//检错 
	i = pcb[i].cur;
	j++;
}
	printf("\n\n");
    printf("\t\t\t\t space剩余%d .",j);
    return j;
} 

//找出空值尾部函数 
int space_last(struct pcb *pcb){
	int i,j;
	i=0;
	j=0;
	while(pcb[i].cur>=0){
	//printf("%d -> ",pcb[i].pid);//检错 
	i = pcb[i].cur;
}
    //printf("space最后一个pcb块为%d",pcb[i].pid);//检错 
    return i;
} 

// 输出测试空值函数
void test_space(struct pcb *pcb){
	int i,j;
	i=0;
	printf("\n\n");
	while(pcb[i].cur>=0){
	printf("%d -> ",pcb[i].pid);
	i = pcb[i].cur;
}

	printf("%d >>>",pcb[i].pid);
	printf("遍历完成!\n");
	printf("\n\n");
}

//测试ready函数
int ready_number(struct pcb *pcb,int ready){
	int j=0;
	printf("ready里的pcb内部标号为:");
	while(pcb[ready].cur!=-999){
		ready=pcb[ready].cur;
		j++;
		//printf("11");//检错 
	}
	printf("ready有:%d",j);//检错 
	return j;
} 

//输出测试ready里的pcb块函数
void test_ready(struct pcb *pcb,int ready){
	
	printf("\n\n");
	printf("\n ready里的pcb内部标号为:\n");
	while(pcb[ready].cur!=-999){
			ready=pcb[ready].cur;//去除ready里头部 
			printf("pid: %d   ",pcb[ready].pid);
			printf("s: %d   ",pcb[ready].s);
			printf("name: %c   ",pcb[ready].name);
			printf("ts: %d   ",pcb[ready].ts);
			printf("job: %d   -->>   ",pcb[ready].job);
			//printf("11");//检错 	
	}
	printf("****遍历完成****\n");
	printf("\n\n");
}


void show_ready(struct pcb *pcb,int ready){
	
	printf("\n ready里的进程详细信息:\n");
	while(pcb[ready].cur!=-999){
			ready=pcb[ready].cur;//去除ready里头部 
			printf("name: %c   ",pcb[ready].name);
			printf("pid: %d   ",pcb[ready].pid);
			printf("s: %d   ",pcb[ready].s);
			printf("ts: %d   ",pcb[ready].ts);
			printf("job: %d   ",pcb[ready].job);
			printf("cur: %d   -->>   ",pcb[ready].cur);
			//printf("11");//检错 	
	}
	printf("展示完成\n\n");
}

//创建就绪态pcb函数 
int creat_pcb(struct pcb *pcb,int space,int ready,int c){//指明space的头部,ready的头部 

	printf("\n\n");
	char pcb_name;
	int previous_1,previous_2,pcb_job;
	while(pcb[space].cur!=-999){
	//	printf("12");//检错
		previous_1=space;
		space=pcb[space].cur; 	
	}
	while(pcb[ready].cur!=-999){
		//printf("233333");//检错 
		ready=pcb[ready].cur;
	}
	if(pcb[space].pid==0){
		printf("\t\t\t\t--空闲pcb块不够,无法创建新进程--\n");
	}
	else{
		c=c+2;//系统时间+2  代表创建进程所需时间为2 
		printf("\t\t\t\t请输入要创建的进程的名称:");
		getchar();
		scanf("%c",&pcb_name);
		printf("\t\t\t\t请输入要创建的进程的工作量:");
		getchar();
		scanf("%d",&pcb_job);
		pcb[previous_1].cur=-999;//space拿下来的pcb的前一个pcb的cur赋值为-999 
		pcb[ready].cur=space;//ready尾部cur赋值链接新的pcb 
		pcb[space].cur=-999;//ready新的pcb作为尾部后,cur赋值为-999 
		pcb[space].name=pcb_name;
		pcb[space].job=pcb_job;
		pcb[space].jobn=pcb_job;
		pcb[space].s=0;
		pcb[space].ts=c; //新创建的pcb的就绪开始时间ts 
	}
	return c;	
	printf("\n\n");
}

//调度就绪态到运行态函数
int ready_to_run(struct pcb *pcb,int ready_head,int space_last,int time,int c){
	
	
	printf("\n\n");
	//一次运行一个时间片给一个进程使用   满足导员要求 
	int ready_last,ready_front,ready_tail,T;
	float W;
	if(pcb[ready_head].cur==-999){
		printf("\n无可运行的进程\n");
		return c;
	}
	else{
		ready_front=pcb[ready_head].pid;//保留头部的地址位置 
		ready_last=pcb[ready_head].cur;//排除ready头部
		pcb[ready_last].job=(pcb[ready_last].job-time);//运行一个时间片 
		pcb[ready_last].s=1;//状态转化为运行态 
		if(pcb[ready_last].job<=0){//判断 
			pcb[ready_last].s=-1;//回复状态为空闲态 
			c=c+pcb[ready_last].job+time;//系统时间(不必等时间片全部用光) 
			pcb[ready_last].tf=c;//tf等于结束时的系统时间 
			pcb[space_last].cur=pcb[ready_last].pid;//空闲块末尾回收运行完的进程 
			pcb[ready_front].cur=pcb[ready_last].cur;//ready里更改去除pcb块前面一个pcb块的cur 
			pcb[ready_last].cur=-999;//空闲块尾部的cur赋值-999 
			T=pcb[ready_last].tf-pcb[ready_last].ts;//周转时间 
			W=((pcb[ready_last].tf-pcb[ready_last].ts)*1.0/pcb[ready_last].jobn);//带权周转时间
			printf("\t\t\t\t<ts: %d  ",pcb[ready_last].ts); 
			printf("tf: %d>",pcb[ready_last].tf); 
			printf("\n\t\t\t\tpid:%d    name: %c   运行完成--",pcb[ready_last].pid,pcb[ready_last].name);
			printf("周转时间:%d  |  带权周转时间:%.2f\n",T,W);	
		}
		else{//运行完一次后就放到ready的尾部 
			ready_tail=pcb[ready_last].pid;
			c=c+time;
			if(pcb[ready_tail].cur!=-999){//ready里是否只有一个pcb块 
				while(pcb[ready_tail].cur!=-999){
					ready_tail=pcb[ready_tail].cur;//向下跳 
				}
				pcb[ready_last].s=0;//状态转化为就绪态ready 
				c=c+2;//运行态向就绪态转换所废时间 
				pcb[ready_front].cur=pcb[ready_last].cur;//ready头部指向当前pcb块的下一跳 
				pcb[ready_tail].cur=pcb[ready_last].pid;//ready尾部指向当前pcb块 
				pcb[ready_last].cur=-999;//尾部赋值	
			}		
		}	
	}
	
	
	
	//一次运行多个时间片,直到一个进程完成后结束 
	/*int j=0,ready_last,ready_last_ssp,ready_front,T,xpz=1;//先来先服务的 
	struct pcb bijiao;
	float W;
	bijiao.job=999999;
	ready_last=ready_head;//ready的头部pcb 
	while(pcb[ready_last].cur!=-999){//先来先服务算法 
		ready_front=pcb[ready_last].pid;//保留前一个的地址位置 
		ready_last=pcb[ready_last].cur;//除去头部第一个 
		//printf("*name: %c ->",pcb[ready_last].name);//输出进程外部名字,检错 
		pcb[ready_last].s=1;//运行态 
		c=c+2;//就绪态向运行态转变花费的时间 
		if(pcb[ready_last].job>=time){
			pcb[ready_last].job=(pcb[ready_last].job-time);//运行时间片
			c=c+time;  
		}else{
			pcb[ready_last].job=(pcb[ready_last].job-time);
			if(pcb[ready_last].job<=0){//判断 
				pcb[ready_last].s=-1;//回复状态为空闲态 
				c=c+pcb[ready_last].job+time;//系统时间(不必等时间片全部用光) 
				pcb[ready_last].tf=c;//tf等于结束时的系统时间 
				pcb[space_last].cur=pcb[ready_last].pid;//空闲块末尾回收运行玩的进程 
				pcb[ready_front].cur=pcb[ready_last].cur;//ready里更改去除pcb块前面一个pcb块的cur 
				pcb[ready_last].cur=-999;//空闲块尾部的cur赋值-999 
				T=pcb[ready_last].tf-pcb[ready_last].ts;//周转时间 
				W=((pcb[ready_last].tf-pcb[ready_last].ts)*1.0/pcb[ready_last].jobn);//带权周转时间
				printf("<ts: %d  ",pcb[ready_last].ts); 
				printf("tf: %d>",pcb[ready_last].tf); 
				printf("\npid:%d  name: %c 运行完成--",pcb[ready_last].pid,pcb[ready_last].name);
				printf("周转时间:%d  |  带权周转时间:%.2f\n",T,W);	
			}	
		}		
	}*/
	
	
	
	printf("\n\n");
	return c;
}
 
// 主函数 
 void main(){
 	int ssp,N/*申请pcb的数目*/,a/*就绪态头部位置偏移*/,i/*space的头部pid*/,j/*ready的头部pid*/,space_rest/*space中剩余空闲pcb数目*/,
	 xpz/*小瓶子*/,aa/*普通变量*/,bb/*接收space中最后一个pcb的下标*/,time/*时间片*/,c=0/*系统时间轴*/;
 	printf("请输入申请的pcb块的数量:");
 	scanf("%d",&N);
 	getchar();
 	struct pcb pcb[N],*ready,*space,*run;
 	init(pcb,N);//初始化进程 
 	test_space(pcb);//测试space中的cur 
 	printf("指定就绪态态头部的pcb块编号(1-%d):",(N-1));
 	scanf("%d",&a);
 	printf("\n");
 	printf("设置时间片大小:");
 	scanf("%d",&time);
 	printf("\n");
 	system("cls");
 	if(a<N&&a>0){
 		space= pcb+0;
 		i=space->pid;
 		ready = pcb+a;
 		j=ready->pid;
		pcb[a-1].cur=pcb[a].cur;//更改space中就绪态前一个pcb中cur的值 
 		pcb[a].cur=-999;//就绪态头部是cur赋值为-999
 		while(ssp!=-1){
 			printf("\n");
 			printf("\t\t\t\t**********************************************\n");
 			printf("\t\t\t\t---------------------菜单---------------------\n");
 			printf("\t\t\t\t|1.遍历space中的pcb块\t");
 			printf("2.遍历ready中的pcb块 |\n");
 			printf("\t\t\t\t|3.创建新的进程\t\t");
 			printf("4.调用运行进程       |\n");
 			printf("\t\t\t\t|5.查看进程情况\t\t");
 			printf("6.清除屏幕           |\n");
 			printf("\t\t\t\t|7.退出程序\t\t"); 
 			printf("                     |\n");
 			printf("\t\t\t\t----------------------------------------------\n");
 			printf("\t\t\t\t********************孙苏平***********************\n");
 			printf("\t\t\t\t请选择功能:");
 			getchar();
 			scanf("%d",&ssp);
 			switch(ssp){
 				case 1:{
 						test_space(pcb);
					break;
			 	}
			 	case 2:{
			 			test_ready(pcb,j);
					break;
			 	}
			 	case 3:{
			 			space_rest=space_number(pcb);
			 			printf("请输入创建的进程数目:");
			 			scanf("%d",&xpz);
			 			if(xpz<=space_rest){
			 				for(aa=1;aa<=xpz;aa++)
			 					c=creat_pcb(pcb,i,j,c);	//创建进程,并返回花费时间 
						}
						else{
							printf("\t\t\t\t空闲pcb块不够多,无法创建新进程!\n");	
						}	
					break;
				}
			 	case 4:{
			 			
						bb=space_last(pcb);
			 			c=ready_to_run(pcb,j,bb,time,c);
			 			test_ready(pcb,j);
					break;
			 	}
			 	case 5:{
			 		show_ready(pcb,j);
					break;
				 }
				 case 6:{
			 		system("cls");
					break;
				 }
			 	case 7:{
			 			ssp=-1;
					break;
			 	}	
			 	default:{
			 			printf("\t\t\t\t不规范,请重新选择!");
					break;
			 	}
		 	}
		}
	}
	else{
		printf("\t\t\t\t值不规范,程序将自动退出!"); 
	}	
 }

三、总结

这是在之前那一篇的基础上修改过来的,调用一次仅仅运行一个进程,进程的时间片用完后就回到就绪态的队尾。因为之前写的源程序是运行一次后就将整个就绪态里的进程都运行,直到全部运行完一遍后或者遇到工作完成的pcb块时才停止工作。然后,被老师说应该要一次运行一个程序才好,就在此基础上做了改进。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
进调度是操作系统中非常重要的一部分,其主要功能是为了合理地利用系统资源,提高系统的运行效率。在 Python 中模拟进程调度可以通过模拟进程的状态、优先级和时间片等来实现。 下面是一个简单的模拟进程调度的示例代码: ```python # 定义进程类 class Process: def __init__(self, pid, name, priority, burst_time): self.pid = pid # 进程ID self.name = name # 进程名称 self.priority = priority # 进程优先级 self.burst_time = burst_time # 进程执行时间 self.wait_time = 0 # 进程等待时间 self.turnaround_time = 0 # 进程周转时间 def __repr__(self): return f"Process {self.pid} ({self.name}): priority={self.priority}, burst_time={self.burst_time}" # 定义进程调度器类 class Scheduler: def __init__(self, processes): self.processes = processes # 进程列表 self.time_quantum = 2 # 时间片大小 # 先来先服务调度算法 def fcfs(self): current_time = 0 total_wait_time = 0 total_turnaround_time = 0 for process in self.processes: process.wait_time = current_time process.turnaround_time = process.wait_time + process.burst_time total_wait_time += process.wait_time total_turnaround_time += process.turnaround_time current_time += process.burst_time avg_wait_time = total_wait_time / len(self.processes) avg_turnaround_time = total_turnaround_time / len(self.processes) print("先来先服务调度算法:") print(f"平均等待时间:{avg_wait_time:.2f}") print(f"平均周转时间:{avg_turnaround_time:.2f}") # 时间片轮转调度算法 def round_robin(self): current_time = 0 total_wait_time = 0 total_turnaround_time = 0 queue = self.processes.copy() while queue: process = queue.pop(0) if process.burst_time > self.time_quantum: process.burst_time -= self.time_quantum current_time += self.time_quantum queue.append(process) else: process.wait_time = current_time process.turnaround_time = process.wait_time + process.burst_time total_wait_time += process.wait_time total_turnaround_time += process.turnaround_time current_time += process.burst_time avg_wait_time = total_wait_time / len(self.processes) avg_turnaround_time = total_turnaround_time / len(self.processes) print("时间片轮转调度算法:") print(f"平均等待时间:{avg_wait_time:.2f}") print(f"平均周转时间:{avg_turnaround_time:.2f}") # 测试 processes = [ Process(1, "P1", 2, 5), Process(2, "P2", 1, 3), Process(3, "P3", 3, 8), Process(4, "P4", 4, 6), Process(5, "P5", 5, 4), ] scheduler = Scheduler(processes) scheduler.fcfs() scheduler.round_robin() ``` 该代码定义了进程类和进程调度器类,并实现了先来先服务调度算法和时间片轮转调度算法。测试时创建了 5 个进程,并分别用两种算法进行调度,输出了平均等待时间和平均周转时间。 需要注意的是,该示例代码只是一个简单的模拟,实际的进程调度算法还需要考虑更多的因素,如进程的状态转换、中断、优先级调度等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玻璃瓶和纸飞机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值