⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3.cpp

📁 cerete your proce
💻 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 + -