一、实验题目
进程的状态及其转换。
二、实验目的
自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的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(); //调用进程运行函数
}
实验运行结果图: