操作系统:进程状态转换模拟,C语言实现

编写并调试一个模拟的进程调度和进程状态转换过程,采用“基于时间片轮转法”调度算法对N(N不小于5)个进程进行调度。要求使用C/C++编程实现(如有难度也可酌情使用Java或C#实现)。首先绘制流程图,然后将程序源代码和运行效果放入实验报告中。
简单轮转法的基本思想是:所有就绪进程按先来先服务的方式排成一个队列,总是把处理机分配给队头的进程,各进程占用CPU的时间片长度相同(如1个CPU时间单位)。当把处理机分配给队头的进程后,该进程出就绪队列,并将进程状态从就绪态变化为运行态。如果运行进程用完它的时间片后还未完成,就把它送回到就绪队列的末尾,同时将进程状态从运行态变换为就绪态,把处理机重新分配给就绪队头的进程。当进程所需的CPU时间全部被满足后,将该进程加入已完成运行进程队列,并记录其完成时间(第几个CPU时间片单位时完成)。直至所有的进程运行完毕。
程序源代码中必须显著注释标明PCB的数据结构(用于记录模拟的进程的状态、完成时间和链接信息等)。需要在程序运行时打印输出版权信息:如姓名、班级、学号。
随机生成N>3个进程(也可以手动顺序录入进程个数和每个进程,按生成/录入顺序组成就绪队列),并生成/录入每个进程的时间片需求,模拟各个进程运行过程。比如录入3个进程分别为P1、P2、P3,需求的CPU时间分别为5、3、4个时间片单位,那么程序模拟该3个进程的运行及状态转换过程,输出为:
T1时刻:P1使用了1个CPU时间片,P1需求剩余时间片为4,就绪队列为P2(3个时间片)->P3(4个时间片),运行完成的进程为:空。
T2时刻:P2使用了1个CPU时间片,P2需求剩余时间片为2,就绪队列为P3(4个时间片)->P1(4个时间片),运行完成的进程为:空。
T3时刻:P3使用了1个CPU时间片,P3需求剩余时间片为3,就绪队列为P1(4个时间片)->P2(2个时间片),运行完成的进程为:空。
T4时刻:P1使用了1个CPU时间片,P1需求剩余时间片为3,就绪队列为P2(2个时间片)->P3(3个时间片),运行完成的进程为:空。

C代码如下(VS2019):

#include<stdio.h>
#include<stdlib.h>
struct ProcessOfMy
{//定义进程
	int name;
	int timeRequire;
	//1为就绪态,0为运行态,-1为已经完成
	int currentState;
	ProcessOfMy* next;
};
typedef struct ProcessOfMy PCB;
struct PCBQueue
{//定义PCB队列
	int numOfProcess=0;
	ProcessOfMy *front, *rear;
	
};
typedef struct PCBQueue PCBQueue;

PCB* InitPCBQuee(PCB* process)
{
	PCB*queue = (PCB*)malloc(sizeof(PCB));
	if (queue == NULL)
	{
		return NULL;
	}
	queue->next=NULL;
	process = queue;
	return process;
}

PCB* EnProcess(PCB*rear,int a)
{//加入队列
	PCB* p = (PCB*)malloc(sizeof(PCB));
	if (p == NULL)
	{
		return NULL;
	}
	int timeRequire = rand()%15;
	p->currentState = 1;
	p->timeRequire = timeRequire;
	p->name = a;
	p->next = NULL;
	rear->next = p;
	rear = p;
	return rear;
}

PCB* DeProcess(PCB* front, PCB* rear)
{//从队列中删除
	PCB* p;
	p = front;
	front = front->next;
	p->next = NULL;
	rear->next = front;
	
	return front;
}

PCB* SchProcess(PCB*front, PCB*rear)
{//将完成一个时间片的进程加入队尾
	rear->next = front;
	return rear;
}

void ChangeCurrentState(PCBQueue  *PCB)
{//若队头程序完成,改变该进程的状态
	PCB->front->currentState = -1;

}

void PrintReadyProcess(PCBQueue *pcbQueue)
{//打印出就绪队列中的进程
	printf("就绪队列有%d个程序:\n", pcbQueue->numOfProcess);
	PCB* p;
	int i;
	
	for (p = pcbQueue->front,i=0;i!=pcbQueue->numOfProcess;i++,p = p->next)
	{
		printf("进程%d(剩余%d单位时间片)\n", p->name, p->timeRequire);
		
	}
	printf("\n");
}



int main()
{
	printf("2018015276 软件18-2 张政威");
	PCB   process, * front, * rear,*cpFront,*cpRear,cpProcess,*p,*p1;
	//创建PCB
	PCBQueue pcbQueue;
	//初始化就绪队列
	front = rear = InitPCBQuee(&process);
	//初始化已完成队列
	cpFront=cpRear= InitPCBQuee(&cpProcess);
	int i;
	for (i = 0;i < 5;i++)
	{//初始化进程
		rear = EnProcess(rear, i);
		if (i == 0)
		{
			front = rear;
		}
		pcbQueue.rear = rear;
		pcbQueue.numOfProcess++;
		printf("进程%d 时间片要求%d\n", rear->name, rear->timeRequire);

	}
	//队尾指向队头形成循环队列
	rear->next = front;

	pcbQueue.front = front;
	pcbQueue.rear = rear;
	

	printf("\n");

	while (pcbQueue.numOfProcess!=0)
	{
		//对第一个进程操作并且操作完之后判断
		pcbQueue.front->timeRequire--;
		printf("进程%d使用了一个CPU时间片,还需要%d个时间片\n", pcbQueue.front->name, pcbQueue.front->timeRequire);

		if (pcbQueue.front->timeRequire == 0)
		{//判断第一个进程是否完成,若完成则释放并且进程数减一
			printf("进程%d完成,出队\n", pcbQueue.front->name);
			ChangeCurrentState(&pcbQueue);
			p = pcbQueue.front;
			//从队列中删除队头已完成的进程
			pcbQueue.front=DeProcess(pcbQueue.front, pcbQueue.rear);
			p->next = NULL;
			//将删除的进程加入已完成队列,并且输出整个已完成队列的名单
			cpRear->next = p;
			cpRear = p;
			printf("已完成的进程有:");
			for (p1 = cpFront->next;p1 != NULL;p1 = p1->next)
			{
				printf("%d ", p1->name);
			}
			printf("\n");
			//PCB中就绪进程数减一
			pcbQueue.numOfProcess--;
			PrintReadyProcess(&pcbQueue);
			continue;
		}
		//队头,队尾前进
		pcbQueue.rear = pcbQueue.rear->next;
		pcbQueue.front = pcbQueue.front->next;
		PrintReadyProcess(&pcbQueue);

	}
	printf("作者信息C语言实现\n");
	return 1;
	
}

  • 8
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值