操作系统(OperatingSystem)-模拟进程的创建、终止、阻塞、唤醒

一、实验目的

通过设计并调试创建、终止、阻塞、唤醒原语功能,有助于对操作系统中进程控制功能的理解,掌握操作系统模块的设计方法和工作原理。

二、实验环境

1、硬件:PC机及其兼容机

2、软件Dev-C++ 5.11

三、实验内容

1、设计创建、终止、阻塞、唤醒原语功能函数

2、设计主函数,采用菜单结构

3、设计“显示队列”函数,目的是能将就绪、阻塞队列中的进程信息显示在屏幕上,以供随时查看各队列进程的变化情况。

四、实验要求

1、进程 PCB 中应包含以下内容:

 2、系统总体结构:

 五、功能说明

1、创建:在本实验中,该功能仅实现建立 PCB,初始化 PCB,并将该 PCB 放入就绪队列中。

2、阻塞:在本实验中,实现的功能为,根据用户输入的进程名称查看该进程是否处在运行状态,若处在运行状态,修改该进程 PCB 的状态,并将该进程转入阻塞队列;若该进程处在其它状态,则给出相应的提示信息;若该进程不存在,也需要给出相应的提示信息。 

3、唤醒:功能类似阻塞功能(注意:若阻塞队列为空,则不能执行唤醒功能)

4、终止:根据用户输入要结束的进程名称,从就绪队列、阻塞队列和正在运行的进程中找到相应的进程 PCB,并将该 PCB 从相应队列中删除。若该进程不存在,需要给出提示。

5、显示:将就绪队列、阻塞队列中的进程列表和正在运行的进程显示出来。

六、源代码解析

PCB的创建

typedef struct P_node{
	char p_name[20];
	float p_time;
	int p_rate;     //优先级
	int p_sta;      //状态
	struct P_node *next;
}*PCB,P_node;

链表的插入和删除操作

//队列插入 
void pqueueand(PCB L, PCB p)
{
	PCB q;
	q = L;
	while(1)
	{
		if(q->next == NULL)
		{
			p->next = NULL;
			q->next = p;
			break;
		}
		else
			q = q->next;
	}
}

//队列删除 
void pqueuedel(PCB L, PCB p)
{
	PCB q,t,i;
	i = L;
	q = L->next;
	while(1)
	{
		if(strcmp(q->p_name, p->p_name) == 0)
		{
			t = q->next;
			i->next = t;
			break;
		}
		else
		{
			q = q->next;
			i = i->next;
		}
	}
}

进程名重复检测

int pnametest(PCB L, char pname[])
{
	PCB p;
	p = L->next; 
	while(1)
	{
		if(p == NULL)
		{
			return 1;
			break;
		}
		else if(strcmp(p->p_name, pname) == 0)
		{
			return 0;
			break;
		}
		else
			p = p->next;
	}
}

 链表显示 

void showlist(PCB q)
{
	PCB p;
	p = q->next;
	if(p == NULL) 
		printf("该队列为空\n");
	else
		while(p!=NULL){
			printf("进程名:%s ",p->p_name);
			printf ("进程时间:%.2f ",p->p_time);
			printf("进程优先级:%d ",p->p_rate);
			printf("进程状态:%d\n",p->p_sta);
			p = p->next;
		}
}

进程创建 

void pcreate(PCB ready,PCB run, PCB block)
{
	int flag = 1;
	PCB L,p;
	L = ready;
	char pname[20];
	while(flag == 1)
	{
		printf("-----------------\n");
		printf("请输入进程名:");
		CREATE:
		{
			scanf("%s",pname);
			if(pnametest(ready, pname) == 0 || pnametest(run, pname) == 0||pnametest(block,pname)==0)
			{ 
				printf("已存在此进程名,请重新输入进程名:");
				goto CREATE;
			}
			else
			{
				p = (P_node *)malloc(sizeof(P_node));
				strcpy(p->p_name, pname);
				printf("请输入进程时间:");
				scanf("%f",&p->p_time);
				printf("请输入进程优先级:");
				scanf("%d",&p->p_rate);
				p->p_sta = 0;
				p->next = NULL;
				L->next = p;
				L = L->next;
				printf("是否继续创建进程(1:是 0:否):");
				scanf("%d",&flag);
			}
		}	
	}
}

进程执行

void prun(PCB ready, PCB run)
{
	if(ready->next != NULL)
	{
		PCB p;
		p = ready->next;
		pqueuedel(ready, p);
		pqueueand(run, p);
		p->p_sta = 1;
		printf("执行进程名:%s\n", p->p_name);
		printf ("执行进程时间:%.1f\n",p->p_time);
		printf("执行进程优先级:%d\n",p->p_rate);
		printf("执行进程状态:%d\n",p->p_sta);
	}
	else
		printf("就绪队列为空,不能正常执行调度\n"); 
}

进程阻塞

void pblock(PCB ready, PCB run, PCB block)
{
	PCB p;
	p = run->next;
	printf("进程已切换\n"); 
	pqueuedel(run, p);
	p->p_sta = 2;
	pqueueand(block, p);
	prun(ready, run);
}

进程唤醒

void pwakeup(PCB ready, PCB run, PCB block)
{
	int flag = 1;
	char pname[20];
	PCB p;
	p = block->next;
	while(flag == 1)
	{	
		printf("请输入要唤醒的进程名:");
		scanf("%s",pname);
		while(1)
		{
			if(p == NULL)
			{
				printf("阻塞队列无此进程");
				break; 
			}
			else if(strcmp(p->p_name, pname) == 0)
			{
				pqueuedel(block, p);
				p->p_sta = 0;
				p->next = NULL;
				pqueueand(ready, p);
				if(run->next == NULL)
				{
					prun(ready, run);
				}
				break;
			}
			else
				p = p->next;
		}
		printf("是否唤醒其他进程(1:是 0:否):");
		scanf("%d",&flag);
	}
}

进程撤销

void pdelete(PCB ready, PCB run, PCB block)
{
	int flag = 1;
	char pname[20];
	PCB p;
	while(flag == 1)
	{
		printf("请输入要撤销的进程名:");
		scanf("%s",pname);
		for(p = ready->next;;p = p->next)
		{
			if(p == NULL)
			{
				break;
			}
			else if(strcmp(p->p_name, pname) == 0)
			{
				pqueuedel(ready, p);
				free(p);
				if(run->next == NULL)
				{
					prun(ready, run);
				}
				goto NEXT;
				break;	
			}
			
		}
		for(p = run->next;;p = p->next)
		{
			if(p == NULL)
			{
				break;
			}
			else if(strcmp(p->p_name, pname) == 0)
			{
				pqueuedel(run, p);
				free(p);
				if(run->next == NULL)
				{
					prun(ready, run);
				}
				
				goto NEXT;
				break;
			}
		}
		for(p = block->next;;p = p->next)
		{
			if(p == NULL)
			{
				break;
			}
			else if(strcmp(p->p_name, pname) == 0)
			{
				pqueuedel(block, p);
				free(p);
				if(run->next == NULL)
				{
					prun(ready, run);
				}
				
				goto NEXT;
				break;
			}
		}
		
		printf("内存中没有该进程");
		
		NEXT:
			{
				printf("是否继续撤销其他进程(1:是 0:否):");
				scanf("%d",&flag);
			}
	}
}

进程显示 

void pshow(PCB ready, PCB run, PCB block)
{
	printf("-----------------\n");
	printf("就绪队列:\n");
	showlist(ready);
	printf("-----------------\n");
	printf("执行队列:\n");
	showlist(run);
	printf("-----------------\n");
	printf("阻塞队列:\n");
	showlist(block);
}

 主函数

void main()
{
	PCB ready,run,block;
	int choice;
	int flag = 1;
	ready = (PCB)malloc(sizeof(P_node));
	ready->next=NULL;
	run = (PCB)malloc(sizeof(P_node));
	run->next=NULL;
	block = (PCB)malloc(sizeof(P_node));
	block->next=NULL;
	while(flag==1) 
    {  
         printf("\t 主菜单\n");
         printf("\t1----创建\t\n");
         printf("\t2----运行\t\n");
         printf("\t3----阻塞\t\n");
         printf("\t4----唤醒\t\n");
         printf("\t5----终止\t\n");
         printf("\t6----显示\t\n");
         printf("\t0----退出\t\n");
         printf("请选择操作:");
         scanf("%d",&choice);
		 switch(choice)
		 {
			case 1: pcreate(ready,run,block);break;			
			case 2: prun(ready,run);break;					
			case 3: pblock(ready,run,block);break;
			case 4: pwakeup(ready,run,block);break;			
            case 5: pdelete(ready,run,block);break;			
			case 6: pshow(ready,run,block);break;			
			case 0: flag=0;break;
			default: printf("输入有误,请检查输入\n");break;
		 }
	}
}

(完整版代码附在文段的最后)

七、运行结果

 八、完整代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//PCB的创建
typedef struct P_node{
	char p_name[20];
	float p_time;
	int p_rate;     //优先级
	int p_sta;      //状态
	struct P_node *next;
}*PCB,P_node;

//队列插入 
void pqueueand(PCB L, PCB p)
{
	PCB q;
	q = L;
	while(1)
	{
		if(q->next == NULL)
		{
			p->next = NULL;
			q->next = p;
			break;
		}
		else
			q = q->next;
	}
}

//队列删除 
void pqueuedel(PCB L, PCB p)
{
	PCB q,t,i;
	i = L;
	q = L->next;
	while(1)
	{
		if(strcmp(q->p_name, p->p_name) == 0)
		{
			t = q->next;
			i->next = t;
			break;
		}
		else
		{
			q = q->next;
			i = i->next;
		}
	}
}

//进程名重复检测 
int pnametest(PCB L, char pname[])
{
	PCB p;
	p = L->next; 
	while(1)
	{
		if(p == NULL)
		{
			return 1;
			break;
		}
		else if(strcmp(p->p_name, pname) == 0)
		{
			return 0;
			break;
		}
		else
			p = p->next;
	}
}

//链表显示 
void showlist(PCB q)
{
	PCB p;
	p = q->next;
	if(p == NULL) 
		printf("该队列为空\n");
	else
		while(p!=NULL){
			printf("进程名:%s ",p->p_name);
			printf ("进程时间:%.2f ",p->p_time);
			printf("进程优先级:%d ",p->p_rate);
			printf("进程状态:%d\n",p->p_sta);
			p = p->next;
		}
}

//进程创建 
void pcreate(PCB ready,PCB run, PCB block)
{
	int flag = 1;
	PCB L,p;
	L = ready;
	char pname[20];
	while(flag == 1)
	{
		printf("-----------------\n");
		printf("请输入进程名:");
		CREATE:
		{
			scanf("%s",pname);
			if(pnametest(ready, pname) == 0 || pnametest(run, pname) == 0||pnametest(block,pname)==0)
			{ 
				printf("已存在此进程名,请重新输入进程名:");
				goto CREATE;
			}
			else
			{
				p = (P_node *)malloc(sizeof(P_node));
				strcpy(p->p_name, pname);
				printf("请输入进程时间:");
				scanf("%f",&p->p_time);
				printf("请输入进程优先级:");
				scanf("%d",&p->p_rate);
				p->p_sta = 0;
				p->next = NULL;
				L->next = p;
				L = L->next;
				printf("是否继续创建进程(1:是 0:否):");
				scanf("%d",&flag);
			}
		}	
	}
}

//进程执行 
void prun(PCB ready, PCB run)
{
	if(ready->next != NULL)
	{
		PCB p;
		p = ready->next;
		pqueuedel(ready, p);
		pqueueand(run, p);
		p->p_sta = 1;
		printf("执行进程名:%s\n", p->p_name);
		printf ("执行进程时间:%.1f\n",p->p_time);
		printf("执行进程优先级:%d\n",p->p_rate);
		printf("执行进程状态:%d\n",p->p_sta);
	}
	else
		printf("就绪队列为空,不能正常执行调度\n"); 
}

//进程阻塞 
void pblock(PCB ready, PCB run, PCB block)
{
	PCB p;
	p = run->next;
	printf("进程已切换\n"); 
	pqueuedel(run, p);
	p->p_sta = 2;
	pqueueand(block, p);
	prun(ready, run);
}

//进程唤醒 
void pwakeup(PCB ready, PCB run, PCB block)
{
	int flag = 1;
	char pname[20];
	PCB p;
	p = block->next;
	while(flag == 1)
	{	
		printf("请输入要唤醒的进程名:");
		scanf("%s",pname);
		while(1)
		{
			if(p == NULL)
			{
				printf("阻塞队列无此进程");
				break; 
			}
			else if(strcmp(p->p_name, pname) == 0)
			{
				pqueuedel(block, p);
				p->p_sta = 0;
				p->next = NULL;
				pqueueand(ready, p);
				if(run->next == NULL)
				{
					prun(ready, run);
				}
				break;
			}
			else
				p = p->next;
		}
		printf("是否唤醒其他进程(1:是 0:否):");
		scanf("%d",&flag);
	}
}

//进程撤销 
void pdelete(PCB ready, PCB run, PCB block)
{
	int flag = 1;
	char pname[20];
	PCB p;
	while(flag == 1)
	{
		printf("请输入要撤销的进程名:");
		scanf("%s",pname);
		for(p = ready->next;;p = p->next)
		{
			if(p == NULL)
			{
				break;
			}
			else if(strcmp(p->p_name, pname) == 0)
			{
				pqueuedel(ready, p);
				free(p);
				if(run->next == NULL)
				{
					prun(ready, run);
				}
				goto NEXT;
				break;	
			}
			
		}
		for(p = run->next;;p = p->next)
		{
			if(p == NULL)
			{
				break;
			}
			else if(strcmp(p->p_name, pname) == 0)
			{
				pqueuedel(run, p);
				free(p);
				if(run->next == NULL)
				{
					prun(ready, run);
				}
				
				goto NEXT;
				break;
			}
		}
		for(p = block->next;;p = p->next)
		{
			if(p == NULL)
			{
				break;
			}
			else if(strcmp(p->p_name, pname) == 0)
			{
				pqueuedel(block, p);
				free(p);
				if(run->next == NULL)
				{
					prun(ready, run);
				}
				
				goto NEXT;
				break;
			}
		}
		
		printf("内存中没有该进程");
		
		NEXT:
			{
				printf("是否继续撤销其他进程(1:是 0:否):");
				scanf("%d",&flag);
			}
	}
}

//进程显示 
void pshow(PCB ready, PCB run, PCB block)
{
	printf("-----------------\n");
	printf("就绪队列:\n");
	showlist(ready);
	printf("-----------------\n");
	printf("执行队列:\n");
	showlist(run);
	printf("-----------------\n");
	printf("阻塞队列:\n");
	showlist(block);
}

//主函数 
void main()
{
	PCB ready,run,block;
	int choice;
	int flag = 1;
	ready = (PCB)malloc(sizeof(P_node));
	ready->next=NULL;
	run = (PCB)malloc(sizeof(P_node));
	run->next=NULL;
	block = (PCB)malloc(sizeof(P_node));
	block->next=NULL;
	while(flag==1) 
    {  
         printf("\t 主菜单\n");
         printf("\t1----创建\t\n");
         printf("\t2----运行\t\n");
         printf("\t3----阻塞\t\n");
         printf("\t4----唤醒\t\n");
         printf("\t5----终止\t\n");
         printf("\t6----显示\t\n");
         printf("\t0----退出\t\n");
         printf("请选择操作:");
         scanf("%d",&choice);
		 switch(choice)
		 {
			case 1: pcreate(ready,run,block);break;			
			case 2: prun(ready,run);break;					
			case 3: pblock(ready,run,block);break;
			case 4: pwakeup(ready,run,block);break;			
            case 5: pdelete(ready,run,block);break;			
			case 6: pshow(ready,run,block);break;			
			case 0: flag=0;break;
			default: printf("输入有误,请检查输入\n");break;
		 }
	}
}
  • 25
    点赞
  • 113
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值