操作系统PCB+时间片+运行状态转换模拟

#include<stdio.h>
#include<windows.h>
#include<time.h>
#define working 1
#define free    0
#define Sqsize  5
#define PCBsize 10
#define PCBcreate 0
#define PCBready  1
#define PCBrun    2
#define PCBblock  3
#define PCBend    4
 
typedef struct {
	int front;
	int rear;
	int Data[Sqsize];
}Sq;
typedef struct {
	int id;
	int tasklength;//任务表长度
	int *tasklist;//任务种类:0代表:cpu 其他代表需要的打印机时长 如{0,0,2,0,0}代表;2个单位cpu+2个时长(秒)打印机+2个单位cpu
	int nowfinish;//标记当前完成的任务数
	int status;
}PBC;
PBC P[PCBsize];//进程
Sq ready = { 0,0,{0} };//就绪队列
Sq block = { 0,0,{0} };//阻塞队列
void initSq(Sq S) {
	S.front = 0;
	S.rear = 0;
	for (int i = 0; i < Sqsize; i++) {
		S.Data[i] = 0;
	}
}
bool isEmpty(Sq S) {
	if (S.front == S.rear) {
		return true;
	}
	else {
		return false;
	}
}
void push(Sq &S,int i) {
	if ((S.rear + 1) % Sqsize == S.front) {
		printf("队列已满");
		Sleep(10000);
		printf("队列已满");
		Sleep(10000);
	}
	S.Data[S.rear] = i;
	S.rear = (S.rear + 1) % Sqsize;
}
void pop(Sq &S, int &e) {
	e = S.Data[S.front];
	S.front = (S.front + 1) % Sqsize;
}
void printSq(Sq S) {
	if (isEmpty(S)) {
		printf("空\n");
		return;
	}
	int i=S.front;
	while (1) {
		printf("%d ", S.Data[i]);
		i = (i + 1) % Sqsize;
		if (i == S.rear) break;
	}
	printf("\n");
}
struct{
	int status;
	clock_t starttime;//记录每个进程开始使用IO的时间
	bool tag;//计时暂停
	int nowPCBid;//正在使用打印机的进程号
}IO = {free,clock(),true ,0};
void checkIO() {
	double time = (clock() - IO.starttime) / CLK_TCK;
	//printf("checkIO-time=%lf\n", time);
	if (IO.tag == false) {
		if ((int)time > P[IO.nowPCBid].tasklist[P[IO.nowPCBid].nowfinish]) {
			printf("进程%d打印任务已结束,进入就绪队列\n", IO.nowPCBid);
			IO.status = free;
			P[IO.nowPCBid].nowfinish++;
			push(ready, IO.nowPCBid);
		    P[IO.nowPCBid].status = PCBready;//就绪 
			IO.tag = true;
		}
		else {
			printf("打印机正在被进程%d占用\n", IO.nowPCBid);
		}
	}
}
void runIO(int i) {
	IO.status = working;
	IO.starttime = clock();
	IO.nowPCBid = i;
	IO.tag = false;
}
void fun_cpu() {
	int e = 0;//用于储存进程号
	initSq(ready);
	initSq(block);


	int arr[3][10] = {{ 0,0,0,0,0,2,0,0,0,0 },
		              { 0,0,0,0,0,0,0,0,0,2 },
					  { 0,0,2,0,0,2,0,0,0,0 }};
	for (int i = 0; i < 3; i++) {
		P[i].id = i;
		P[i].tasklength = 10;
		P[i].tasklist = arr[i];
		P[i].nowfinish = 0;
		P[i].status = PCBready;//就绪 
	}
	push(ready, 0); push(ready, 1); push(ready, 2);


	int n = 30;
	while (n--)
	{
		printf("=======================================================\n");
		printf("就绪队列:"); printSq(ready);
		printf("阻塞队列:"); printSq(block);
		//crearenewPCB();//随机创建新进程
		checkIO();//检查打印机状态
		if (IO.status == free && !isEmpty(block) ){
			pop(block, e);
			runIO(e);
			printf("进程%d从 阻塞队列 进入 打印机 \n",e);
		}
		if (isEmpty(ready)) {
			printf("当前无任务需要cpu处理,等待新进程产生\n"); Sleep(1000);
		}
		else {
			pop(ready, e);
		    P[e].status = PCBrun;//执行
			if (P[e].nowfinish < P[e].tasklength) {
				int times = 5;//时间片划分
				while (times--) {
					Sleep(100);
					if (P[e].tasklist[P[e].nowfinish] == 0 && P[e].nowfinish < P[e].tasklength) {
						P[e].nowfinish++;
					}
				}
				printf("进程%d--cpu时间片结束\n", e);
				if (P[e].nowfinish < P[e].tasklength) {
					if (P[e].tasklist[P[e].nowfinish] == 0) {
						push(ready, e);
		    			P[e].status = PCBready;//就绪
						printf("进程%d下一任务是cpu,   进入就绪队列\n", e);
					}
					else {
						push(block, e);
		    			P[e].status = PCBblock;//阻塞 
						printf("进程%d下一任务是打印机,进入阻塞队列\n", e);
					}
				}
				else
				{
		    		P[e].status = PCBend;//终止 
					printf("进程%d所有任务已经全部完成\n", e);
				}
			}
			else {
		    	P[e].status = PCBend;//终止 
				printf("进程%d所有任务已经全部完成\n", e);
			}
		}
	}

}
int main() {
	//printf("Hello  World!");
	fun_cpu();
	return 0;
}

 以前在校学习时写的一些内容,只是简单的对各个进程转换进行了模拟,有错误欢迎指正

1.目的: 自行编制模拟程序,通过形象化的状态显示,深入理解进程的概念、进程之间的状态转换及其所带来的PCB内容 、组织的变化,理解进程与其PCB间的一一对应关系。 2. 内容及要求: 1) 设计并实现一个模拟进程状态转换及其相应PCB内容、组织结构变化的程序。 2) 独立编写、调试程序。进程的数目、进程的状态模型(三状态、五状态、七状态或其它)以及PCB的组织形式可自行选择。 3) 合理设计与进程PCB相对应的数据结构。PCB的内容要涵盖进程的基本信息、控制信息、资源需求及现场信息。 4) 设计出可视性较好的界面,应能反映出进程状态的变化引起的对应PCB内容、组织结构的变化。 5) 代码书写要规范,要适当地加入注释。 6) 认真进行预习,完成预习报告。 7) 实验完成后,要认真总结,完成实验报告。 3.使用的数据结构及说明: 在本实验中,主要用到的数据结构是PCB的结构,其中PCB的数据结构如下: struct PCB { int P_Id; //PCB的ID号 char P_Name[10]; //PCB的名称 char P_State[10]; //PCB状态 int P_Runtime; //PCB的所需要的运行时间 int P_Requiry; //PCB所需要的资源要求 struct PCB * next ; //PCB块的下一个指针 } ; 其中,P_Id,和P_Name用来标示一个进程,而P_State用来标示进程的五种状态:Create_state,Ready_state,Block_state,Run_state,Exit_state。P_Runtime标示要完成一个进程所需要的时间。P_Requiry标示一个进程的执行所需要的其他条件,当其他的条件满足,则P_Requiry置1,否则置0。Struct PCB * next 用来指向同一队列中的下一个PCB块。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值