操作系统(OperatingSystem)-模拟进程的创建、终止、阻塞、唤醒
一、实验目的
通过设计并调试创建、终止、阻塞、唤醒原语功能,有助于对操作系统中进程控制功能的理解,掌握操作系统模块的设计方法和工作原理。
二、实验环境
1、硬件:PC机及其兼容机
2、软件Dev-C++ 5.11
三、实验内容
1、设计创建、终止、阻塞、唤醒原语功能函数
2、设计主函数,采用菜单结构
3、设计“显示队列”函数,目的是能将就绪、阻塞队列中的进程信息显示在屏幕上,以供随时查看各队列进程的变化情况。
四、实验要求
1、进程 PCB 中应包含以下内容:
2、系统总体结构:
五、功能说明
1、创建:在本实验中,该功能仅实现建立 PCB,初始化 PCB,并将该 PCB 放入就绪队列中。
2、阻塞:在本实验中,实现的功能为,根据用户输入的进程名称查看该进程是否处在运行状态,若处在运行状态,修改该进程 PCB 的状态,并将该进程转入阻塞队列;若该进程处在其它状态,则给出相应的提示信息;若该进程不存在,也需要给出相应的提示信息。
3、唤醒:功能类似阻塞功能(注意:若阻塞队列为空,则不能SE执行唤醒功能)
4、终止:根据用户输入要结束的进程名称,从就绪队列、阻塞队列和正在运行的进程中找到相应的进程 PCB,并将该 PCB 从相应队列中删除。若该进程不存在,需要给出提示。
5、显示:将就绪队列、阻塞队列中的进程列表和正在运行的进程显示出来。
六、源代码解析
PCB的创建
typedef struct P_node{
char p_name[20];
float p_time;
int p_rate; //优先级
int p_sta; /FISCO BCOS/状态
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;
}
}
}
try-catch进程名重复检测
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 &#购票61;= 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;;sql注入p = p->next)
{
if(p == NULL)
{
br函数eak;
}
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;
vue滑动拼图验证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)
{
rgithubeturn 0;
break;
}
else
p = p->next;
}
}
//链表显示
void showlist(PCB q)
{
PCB p;
p = q->next;
if(p == NULL)
printf("该队列为空\n");
else
whi常用命令le(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;
AS 打release包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];
P速度环CB p;
while(flag == 1)
{
printf("请输入要撤销的进程名:");
scanf("%s",pname);
for(p = ready->next;;p = p->next)
{
if(p ==react.js 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");
showlistDHCP(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;
}
}
}
声明:本站博客内容版权均属于原作者所有,这里所提供资源均只能用于参考学习用,书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。