📄 3.cpp
字号:
//11.1 实验一代码:
#include "basic.h"
#include <iostream>
using namespace std;
#include "string.h"
pnode *proot;//进程树链表根结点
pnode *plink;//进程树链表指针
bool isExistPc(int pcid)
{
pnode *p;
for(p=plink; p; p=p->next)//遍历进程树链表
{
if(p->node->pid == pcid)//进程存在
return true;//退出
}
return false;
}
//create process of *para
int createpc(int *para)
{
//add your code
pnode *p,*p1,*pp;
for(p=plink; p; p=p->next)//遍历进程树链表
{
if(p->node->pid == para[1]) //找到了新加入进程的父进程pid
{
pp = p;//保存该父进程结点的链表指针
}
}
//创建新进程
p1 = new pnode;//分配新进程结构空间(每次动态创建PCB)
p1->node=new pcb;//创建空白PCB
p1->node->pid = para[0]; //写入新进程PID
p1->node->ppid = para[1];//写入新进程的父进程PPID
p1->node->prio = para[2];//写入新进程的优先级PRIO
p1->node->resource = 0;//获得资源数
p1->node->state = -1;//进入等待队列(-1等待,1执行,0执行完毕)
p1->node->tottime = 0;//等待总时间
p1->sub = NULL;//最老子进程
p1->next = NULL;
p1->brother = NULL;//最大的弟弟进程
//add to process tree
if(!pp->sub)//直接加入到父进程结点下,作为其父进程的第一个孩子
{
pp->sub = p1;//链表中为连接新结点的父亲结点保存其新孩子指针
p1->linkpp = pp;//链表中为新孩子保存连接他的父亲指针
}
else//加入到兄弟结点最后(即父进程结点下的孩子结点最后)
{
for(p=pp->sub;p->brother;p=p->brother);
{
p->brother=p1;//链表中为连接新结点的兄弟结点保存其新兄弟指针
p1->linkpp=p;//链表中为新兄弟保存连接他的兄弟指针
}
}
// add to process link
for(p=plink; p->next; p=p->next);//连接原来在新结点后面的进程树(为新进程分配内存空间和栈空间)
p->next=p1;
return 0;
}
//show process detail
void showdetail()
{
//add your code
pnode *p,*p1;
p = plink;
for( ; p; )
{
//先打印父亲结点
printf("%d(prio %d): ",p->node->pid,p->node->prio);
p1 = p->sub;//指向其下一个孩子进程
//然后打印该父亲的孩子进程的兄弟
for(;p1;)
{
printf("%d(prio %d) ",p1->node->pid,p1->node->prio);
p1 = p1->brother;//指向其下一个兄弟进程
}
printf("\n");
//再打印新的父亲结点
p = p->next;
}
printf("\n");
}
//create process of *para
void SetPcExe(int *para)//执行位于就绪队列队首的某进程
{
pnode *p;
///////////////////////__就绪即cpu与资源可获得
___///////////////////////////////////////////////////
for(p=plink; p; p=p->next)//遍历进程树链表(模拟单处理机,执行某进程前先获得空闲cpu)
{
if(p->node->state == 1 && p->node->pid!=para[0])//若存在其它进程正在被处理
{
p->node->state = 0;//模拟单处理机:该进程执行完毕,并释放cpu。
cout<<"原来正在运行的进程id为 "<<p->node->pid<<" 已经执行完毕;";
if( p->node->resource!=0)//拥有资源
{
p->node->resource = 0;//释放该进程占有的资源
cout<<"并释放所有占有的资源!\n";
}
break;//单处理机释放一次,cpu便空闲了。该进程可以获得cpu
}
}
//////////////////////////////////////////////////////////////////////////
for(p=plink; p; p=p->next)//遍历进程树链表
{
if(p->node->pid == para[0])//若存在将被处理的进程(且假设该进程已是就绪队首)
{ //修改PCB
p->node->resource = 8;//获得8个资源(实际应该是取资源地址)
p->node->state = 1;//该进程处于执行状态
cout<<"进程号为"<<p->node->pid<<"的进程已经获得8个资源并处于执行状态\n";
break;
}
}
}
void DelPcTree(pnode *t)//递归删除树及链表里面t的所有子孙进程(包括t),并释放pcb内存空间
{
if(t == NULL)
return;
pnode *q = t->sub,*p;//q为t的最老孩子结点链表指针
while(q!=NULL)//q存在孩子
{
p = q->brother;//保存q的兄弟指针为p(导致后序遍历)
DelPcTree(q);//后根遍历(查找并删除)q的所有子孙进程
if (t->node->state==1)//处于执行状态
{
t->node->state = 0;//置为停止状态
cout<<"id为 "<<t->node->pid<<" 的进程已经停止执行状态;";
if( t->node->resource!=0)//拥有资源
{
t->node->resource = 0;//释放该进程占有的资源
cout<<"并成功释放占有的所有资源!\n";
}
//(资源的信号量++)
//判断是否有新进程可获得资源和cpu并调用下一个进程
}
q = p;//后根遍历删除q的所有子孙进程
}
pnode *temp;
for(temp=plink; temp!=NULL; temp=temp->next)
{
if(temp->next == t) //find parent pcb
{
temp->next = t->next; //删除单链表里的进程结点
}
}
delete t;//释放进程的原动态申请的空白pcb及链表空间
}
int deletepc(int para)//删除id为para的进程
{
//判断并保存要删除进程的链表指针p1
pnode *p,*p1;
int pflag=0,sflag;
for(p=plink; p; p=p->next) //遍历寻找
{
if(p->node->pid == para) //find parent pcb
{
sflag=1;
p1 = p; //p1为要删除的进程id的链表指针
}
}
if(!sflag) //sflag==0
{
printf("pid %d 还没有被创建!\n",para);
return -3;
}
//从树的父亲及兄弟级删除该进程
bool delpcintree = false;
for(p=plink;p&&!delpcintree;p=p->next)
{
if(p->node->pid == p1->node->ppid) //找到要删除的p1的父进程p
{
if (p->sub==p1)//要删除的进程为其父进程的第一孩子
{
p->sub = p1->brother;
delpcintree=true;
}
else if (p->sub!=p1)//要删除的进程为其父进程的非第一孩子
{
for(pnode*tmp=p->sub; tmp!=NULL; tmp=tmp->brother)//遍历其父进程的孩子进程
{
if (tmp->brother->node->pid == p1->node->pid) //找到要删除进程的哥
哥进程tmp
{
tmp->brother = p1->brother;//删除该进程
delpcintree=true;
break;
}
}
}
}
}
DelPcTree(p1);//要删除进程的链表指针p1
return 0;
}
void CreateTree()
{
int pc[10][3];
pc[0][0] = 1; pc[1][0] = 2; pc[2][0] = 3; pc[3][0] = 4; pc[4][0] = 5;
pc[0][1] = 0; pc[1][1] = 0; pc[2][1] = 0; pc[3][1] = 2; pc[4][1] = 2;
pc[0][2] = 1; pc[1][2] = 1; pc[2][2] = 1; pc[3][2] = 4; pc[4][2] = 4;
pc[5][0] = 6; pc[6][0] = 7; pc[7][0] = 8; pc[8][0] = 9; pc[9][0] = 10;
pc[5][1] = 4; pc[6][1] = 6; pc[7][1] = 5; pc[8][1] = 6; pc[9][1] = 2;
pc[5][2] = 6; pc[6][2] = 1; pc[7][2] = 2; pc[8][2] = 2; pc[9][2] = 2;
int *para;
for (int i=0; i<=9; i++)
{
para = pc[i];//获得参数 [1 0 2]
// cout << pc[i][0]<<" "<< pc[i][1]<<" "<<pc[i][2]<<endl;
// continue;
createpc(pc[i]);//创建进程
cout <<"进程 ("<< para[0]<<","<< para[1]<<","<< para[2]<<") 创建成功!\n";
}
}
void help()//显示帮助信息
{
cout<<" 1.显示当前进程树 show \t 2.创建进程 cpc(id,pid,prio)\t 3.命令提示help\n 4.进程删除 del(id)
\t";
cout<<" 5.执行进程 exe(id)\t\t 6.退出 exit\n\n";
}
//don't change
void main()
{
initerror();//初始化错误信息
short cflag,pflag;
char cmdstr[32];
//创建根进程(0,-1,0)
proot = new pnode;//申请新进程对象空间
proot->node=new pcb;//创建空白进程
proot->node->pid=0;//根进程PID
proot->node->ppid=-1;//父进程pPID
proot->node->prio=0;//根进程优先级prio
proot->next=NULL;//链表指针
proot->sub=NULL;//根进程的子进程
proot->brother=NULL;//根进程的兄弟进程
plink = proot;
CreateTree();//初始化一颗树!!!!!!!!
help();//显示帮助信息
for(;;)
{
cflag = 0;//error comannd
pflag = 0;//error parameter
char str[20]="";
printf("cmd:");
scanf("%s",cmdstr);//输入命令
//exit the programe
if(!strcmp(cmdstr,"exit"))
break;
if(!strcmp(cmdstr,"help")) //显示帮助信息
{
help();
continue;
}
//显示当前进程树
if(!strcmp(cmdstr,"show"))
{
cflag = 1;
pflag = 1;
showdetail();
continue;
}
strncpy(str,cmdstr,3);//把输入命令的前3个字符赋给str,因为不需要判断参数
//创建进程
if(!strcmp(str,"cpc"))
{
int *para;
char *s, *pcid;
s = strstr(cmdstr,"cpc");//"cpc"在cmdstr中第一次出现的位置
if(s)//input is create process
{
cflag=1;
para = (int *)malloc(3);
pcid = substr(s,instr(s,'(')+1,strlen(s)-2);//getparameter [1,0,2]
para = strtoarray(pcid);//获得参数 [1 0 2]
if(!isExistPc(para[0]))//新进程还没有被创建(为新进程申请获得唯一的数字标识
符)
{
if(isExistPc(para[1]))////找到了新加入进程的父进程
{
createpc(para);//创建进程
cout <<"进程("<< para[0]<<","<< para[1]<<","<< para[2]<<")
创建成功!\n\n";
pflag = 1;
continue;
}
cout <<"The process' parent id = "<<para[1]<<"is not exsit!\n\n";
continue;
}
cout <<"The process id = "<<para[0]<<"is already exsit!\n\n";
continue;
}
else if(!pflag)
geterror(1);
}
//执行进程
if (!strcmp(str,"exe") )
{
int *para;
char *s, *s1;
s = strstr(cmdstr,"exe");
if(s)
{
cflag = 1;
para = (int *)malloc(3);
s1 = substr(s,instr(s,'(')+1,strlen(s)-2);
para = strtoarray(s1);
SetPcExe(para);//执行进程
continue;
}
}
if (!strcmp(str,"del") ) //delete process
{
int *para;
char *s, *s1;
s = strstr(cmdstr,"del");//delete process
if(s)
{
cflag=1;
para = (int *)malloc(3);
s1 = substr(s,instr(s,'(')+1,strlen(s)-2);
para = strtoarray(s1);
if( isExistPc(para[0]) )//要删除的进程存在
{
if (para[0] == 0)
{
cout << "你没有权限来删除根进程!\n\n";
continue;
}
cout << "删除前的进程树为:\n\n";
showdetail();
deletepc(para[0]);
cout <<"id为 "<< para[0]<<" 的进程结束成功!"<<"\n删除后的进程树
为:\n\n";
showdetail();
continue;
}
cout <<"你要删除的进程 "<< para[0]<<" 不存在 !\n\n";
continue;
}
}
if(!cflag)
geterror(0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -