进程的状态及其转换实验

一、实验题目

进程的状态及其转换。

二、实验目的

自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的PCB内容 、组织的变化,理解进程与其PCB间的一一对应关系。

三、实验内容与要求

1)设计并实现一个模拟进程状态转换及其相应PCB内容、组织结构变化的程序。
2) 独立编写、调试程序。进程的数目、进程的状态模型(三状态、五状态、七状态或其它)以及PCB的组织形式可自行选择。
3) 合理设计与进程PCB相对应的数据结构。PCB的内容要涵盖进程的基本信息、控制信息、资源需求及现场信息。
4) 设计出可视性较好的界面,应能反映出进程状态的变化引起的对应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块。

五、实验过程

源代码:
#include"stdlib.h"
#include"stdio.h"
#include"string.h"
#include <windows.h> 
/*全局结构体及变量定义*/
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块的下一个指针
};
struct PCB * Create_state;          //创建状态
struct PCB * Run_state;             //运行状态
struct PCB * Ready_state;           //就绪状态
struct PCB * Block_state;           //阻塞状态
struct PCB * Exit_state;            //退出状态
int signal4 = 0;                      //标示进程4的完成状态
int signal5 = 0;                      //标示进程5的完成状态

void InsertQueue(struct PCB **head, struct PCB *node) //将进程插入到队列的尾部
{
	struct PCB * p, *q;
	node->next = NULL;
	if (*head == NULL)                   //如果队列为空
	{
		*head = node;
	}
	else                               //队列不空
	{
		p = *head;
		q = p->next;
		while (q != NULL)                  //找到最后的元素位置
		{
			p = q;
			q = q->next;
		}
		p->next = node;                   //将节点插入队列
	}
}

void DeleteQueue(struct PCB **head, struct PCB *node)//撤销进程,从队列中删除元素
{
	struct PCB *p, *q;
	p = node;
	q = *head;
	if (*head == NULL || node == NULL)                //如果队列为空,返回
		return;
	if (*head == node)                            //如果要删除的元素是队首元素
	{
		*head = (*head)->next;
		return;
	}
	else                                        //如果不是队列的首元素
	{
		while (q->next != p&&q->next != NULL)
			q = q->next;
		q = p->next;
		p->next = NULL;
	}
}

void Display_Process(struct PCB * node)         //打印进程状态的元素函数
{
	printf("\n\nthis process Id is        : %d \n", node->P_Id);
	printf("this process name is      : %s \n", node->P_Name);
	printf("this process state is     : on %s \n ", node->P_State);
	printf("this process Runtime is   : %d \n", node->P_Runtime);
	if (node->P_Requiry)
		printf("this process resource is ready    \n");
	else
		printf("this process resource is not ready ! \n");
}

void DispatchToBlock(struct PCB *node)   //调度到阻塞状态的函数
{
	if (!node->P_Requiry)             //如果所需要的资源没有满足则,调度到阻塞状态
	{
		strcpy(node->P_State, "block");
		InsertQueue(&Block_state, node);      //插入到阻塞队列
		Display_Process(node);
	}
}
void DispatchToReady(struct PCB *node)  //调度到就绪状态的函数
{
	if (node->P_Requiry)                  //如果所需的资源满足,则调度
	{
		strcpy(node->P_State, "Ready");
		InsertQueue(&Ready_state, node);
		Display_Process(node);
	}
}

void DispatchBlockToReady()  //从阻塞状态调度到就绪状态函数
{
	struct PCB*p, *q;
	q = Block_state;
	while (q != NULL)                        //如果阻塞状态队列不空
	{
		p = q;
		q = q->next;
		if (signal4&&p->P_Id == 1)            //如果所需要的资源满足
		{
			p->P_Requiry = 1;
			DeleteQueue(&Block_state, p);   //填空
			strcpy(p->P_State, "ready");
			InsertQueue(&Ready_state, p);   //填空
			printf("process1 will be in the state of ready!\n");
			Display_Process(p);
		}
		if (signal5&&p->P_Id == 2)
		{
			p->P_Requiry = 1;
			DeleteQueue(&Block_state, p);
			strcpy(p->P_State, "ready");
			InsertQueue(&Ready_state, p);
			printf("process2 will be in the state of ready!\n");
			Display_Process(p);
		}
	}
}

void Create_Process()                               //创建进程函数
{
	int i;
	struct PCB *p;
	char name[10];
	strcpy(name, "process");
	for (i = 1;i<3;i++)                         //动态创建2个处于阻塞状态的进程
	{
		p=(struct PCB *)malloc(sizeof(struct PCB));    // 动态的分配空间地址   分配一个 大小为结构体PCB的大小的空间,并把空间地址赋予p
		p->P_Id = i;
		name[7] = i + '0';
		name[8] = '\0';
		strcpy(p->P_Name, name);
		strcpy(p->P_State, "create");
		p->P_Runtime = 1;                         //所需要的时间片为1
		p->P_Requiry = 0;
		Display_Process(p);
		Sleep(4000);
		printf(" \n process%d will be in the state of Block, waiting the resource ready \n\n", i);
		DispatchToBlock(p);                         //同时调度到阻塞队列
	}

	for (i = 3;i<7;i++)                             //创建4个就绪状态的队列
	{
		p=(struct PCB *)malloc(sizeof(struct PCB));    //动态的分配空间地址   分配一个 大小为结构体PCB的大小的空间,并把空间地址赋予p
		p->P_Id = i;
		name[7] = i + '0';
		name[8] = '\0';
		strcpy(p->P_Name, name);
		strcpy(p->P_State, "create");
		p->P_Requiry = 1;
		if (i == 6)                                //在这里个进程6所需要的时间片为2
			p->P_Runtime = 2;
		else
			p->P_Runtime = 1;
		Display_Process(p);
		Sleep(4000);
		printf(" \n process%d will be in the state of Ready, waiting to run \n\n", i);
		DispatchToReady(p);
	}
}

void display(struct PCB **head)               //打印各个状态队列里进程数目
{
	struct PCB *p;
	p = *head;
	while (p != NULL)
	{
		Sleep(2000);
		printf("\n\nthis process Id is        : %d \n", p->P_Id);
		printf("this process name is      : %s \n", p->P_Name);
		printf("this process state is     : on %s \n ", p->P_State);
		printf("this process Runtime is   : %d \n", p->P_Runtime);
		if (p->P_Requiry)
			printf("this process resource is ready    \n");
		else
			printf("this process resource is not ready ! \n");
		p = p->next;
	}
}

void Process_Run()                              //进程运行函数
{
	struct PCB *p;
	while (Ready_state != NULL)                     //就绪队列不空则继续执行                         
	{
		p = Ready_state;
		if (p->P_Runtime <= 0) break;               //如果时间片执行完了,则跳出循环
		strcpy(p->P_State, "running");
		Display_Process(p);
		p->P_Runtime = p->P_Runtime - 1;
		Sleep(4000);
		if (p->P_Runtime>0)                    //没有完成,则进入就绪队列
		{
			printf("this process is not finished,will be dispatch to the ready queue!!\n");
			DeleteQueue(&Ready_state, p);
			strcpy(p->P_State, "ready");
			InsertQueue(&Ready_state, p);
			Display_Process(p);
		}

		else                              //执行完成,则跳出,并发送相应的信息
		{
			printf("\n\nProcess%d is finished and will be in the state of exit!\n\n", p->P_Id);
			if (p->P_Id == 4) signal4 = 1;
			if (p->P_Id == 5) signal5 = 1;
			DeleteQueue(&Ready_state, p);
		}
		if (signal4 || signal5)
			DispatchBlockToReady();       //如果资源满足,则将进程调度到就绪队列
	}
	if (Ready_state == NULL)
		printf("\nthere is no process ready!\n    STOP Machine!!!\n");
}

void main(int argc, char * argv[])                //主函数
{
	char c = 'c';                              //界面
	printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");
	printf("......Press s to start the process.......\n");
	scanf("%c", &c);
	while (1)
	{
		if (c == 's' || c == 'S')break;
		scanf("%c", &c);
	}

	Create_Process();                            //调用创建进程函数
	printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
	printf("\n>>>>>>> Display the Ready queue  >>>>>>>>>>>>>>>\n");
	Sleep(5000);
	display(&Ready_state);         显示就绪队列里的进程
	printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
	printf("\n>>>>>>>> Display the Block queue   >>>>>>>>>>>>\n");
	Sleep(5000);                                 //显示阻塞队列函数
	display(&Block_state);         /
	printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n\n");
	printf("\n>>>>>>>>  Now the process start to run     >>>>>>>>>>>\n");
	Sleep(5000);
	Process_Run();                               //调用进程运行函数  
}

实验运行结果图:

在这里插入图片描述

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、付费专栏及课程。

余额充值