操作系统实验--C语言模拟进程管理

实验二 进程管理
1、目的要求
(1)熟悉进程概念
(2)熟悉进程状态转换和进程控制块的组成
2、实验内容
(1)进程创建原语
(2)进程调度原语
(3)进程的组织
---------------------------
进程状态变换:因阻塞需要更复杂的数据结构,例如阻塞条件和激活条件
这里我只讨论从就绪队列将进程调入运行队列的情况
因此本实验只有两个队列
1.就绪队列
2.运行队列
C语言源代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include <string.h>
#include<windows.h>
#define PCBCOUNT 6
#define MAXTIME PCBCOUNT*20
#define PCB_NAME_LENGTH 5
typedef struct PCB//PCB
{
	int PID;
	
	int cTime;
	int nTime;
	char Pname[PCB_NAME_LENGTH];
	struct PCB * next;
}P,*PPoint;
PPoint CreatePCB(void)//创建PCB 
{
	int order=0;
	srand(time(NULL));
	PPoint head=(PPoint)malloc(sizeof(P));
	PPoint s,r,p;
	r=head;
	while(order<PCBCOUNT)
	{
		int i,c;char name[PCB_NAME_LENGTH];name[PCB_NAME_LENGTH-1]='\0';
		s=(PPoint)malloc(sizeof(P));
		s->PID=++order;
		s->cTime=order;
		s->nTime=rand()%98+1;
		for(i=0;i<PCB_NAME_LENGTH-1;i++)
		{
			c=rand()%51;
			if(c<26)
			name[i]=(char)(c+65);
			else
			name[i]=(char)(c+71);
		}
		strcpy(s->Pname,name);
		s->Pname[PCB_NAME_LENGTH-1]='\0'; 
		r->next=s;
		r=s;
	}
	r->next=NULL;
	printf("进程ID\t进程名\t\t到达时间\t运行时间\n");
	p=head->next;
	while(p!=NULL)
	{
		printf("%d\t%s\t\t%d\t\t%d\n",p->PID,p->Pname,p->cTime,p->nTime);
		p=p->next;
	}
	return head;
}
int deleteP(PPoint head,PPoint del)//删除进程 
{
	PPoint temp=head;
	if(head==NULL||head->next==NULL)
	return 0;
	else
	{
		while(temp->next!=del)temp=temp->next;
		if(del->next!=NULL)
		{
			temp->next=del->next;
		}
		else
		{
			temp->next=NULL;
		}
		printf("进程:%d--%s\t运行完毕,已删除\n",del->PID,del->Pname);
		free(del);
		if(head->next==NULL)
		return 0;
		else
		return 1;
	}
}
/*
调度函数说明
将src所指进程插入到des所指队列队尾 
*/
void schedule(PPoint run,PPoint ready)//des:目的队列 src:目标进程 
{
	PPoint temp;
	if(ready->next!=NULL)
	{
		temp=ready->next;
		temp->PID+=PCBCOUNT;
		while(run->next!=NULL)run=run->next;
		ready->next=temp->next;
		temp->next=NULL;
		run->next=temp;
	}
} 
//调度算法以及查找函数
/*
最短剩余时间优先算法介绍
从运行队列队首开始执行,每执行一次(单位时间)后
如果 该进程执行完毕就删除该进程
否则 扫描整个队列里剩余时间最短的进程
并执行该进程一次(单位时间)后再次扫描执行
直至所有进程执行完毕 
*/
void SRTF()//最短剩余时间优先算法实现 
{
	printf("您选择的算法是SRTF算法\n");
	printf("---------------运行队列----------------\n");
	PPoint p=CreatePCB();
	Sleep(1000);
	printf("---------------就绪队列----------------\n");
	PPoint q=CreatePCB();
	PPoint num,now,del;
	char show[2*PCBCOUNT][2*MAXTIME];
	int runflag=1,counter=0,rflag=1,i,j;
	for(i=0;i<2*PCBCOUNT;i++)
		for(j=0;j<2*MAXTIME;j++)
		show[i][j]=' ';
	now=p;
	printf("--------------SRTF算法执行中---------------\n");
	while(runflag!=0)
	{
		counter++;
		//printf("WHILE阻塞\n");
		del=p->next;//重置 
		num=p->next;//重置指针
		if(now!=NULL&&rflag!=0)//就绪队列依次送运行队列 
		{
			now=now->next;
		}
		else rflag=0;
		if(rflag==1)
		{
			
			while(num!=now)
			{	//printf("IF1阻塞\n"); 
				if(del->nTime>num->nTime)
				{
					del=num;
				}
				num=num->next;
			}
		}
		else
		{
			while(num!=NULL)
			{	//printf("ELSE1阻塞\n");
				if(del->nTime>num->nTime)
				{
					del=num;
				}
				num=num->next;
			}
		}
		if(del->nTime>5)
		{
			del->nTime-=5;show[del->PID-1][counter]='-';
			//printf("ID:%d\t进程:%s \t剩余%d\n",del->PID,del->Pname,del->nTime);
		}
		else
		{
			//printf("ID:%d\t进程:%s\t执行完毕!\t",del->PID,del->Pname);
			show[del->PID-1][counter]='-';
			runflag=deleteP(p,del);
			schedule(p,q);	
		}
		//printf("%d",counter);
	}
	printf("---------------算法运行序列----------------\n");
	for(i=2*PCBCOUNT;i>0;i--)
	{	printf("%d",i);
		for(j=0;j<counter;j++)
		printf("%c",show[i-1][j]);
		printf("\n");
	}
}
/*
先来先服务算法介绍
在运行队列中依次执行进程
直至全部进程执行完毕 
*/
void FCFS()//先来先服务算法实现 
{
	printf("你选择的算法是先来先服务算法FCFS\n");
	printf("---------------运行队列----------------\n");
	PPoint head=CreatePCB();
	PPoint p=head;
	Sleep(1000);
	printf("---------------就绪队列----------------\n");
	PPoint q=CreatePCB();
	printf("--------------FCFS算法执行中---------------\n");
	while(p->next!=NULL)
	{
		deleteP(head,p->next);
		schedule(head,q); 
	}
	printf("---------------算法运行序列----------------\n");
	printf("此算法依次执行队列进程,故不展示运行序列\n");
}
/*
时间片轮转算法介绍
每个进程每次执行指定时间
如果在时间片内进程全部执行完成则删除该进程
否则将该进程置于运行队列尾部
直至所有进程执行完 
*/
void RR()//时间片轮转算法实现 
{
	printf("你选择的算法是时间片轮转算法RR\n");
	printf("---------------运行队列----------------\n");
	PPoint p,head=CreatePCB();
	Sleep(1000);
	printf("---------------就绪队列----------------\n");
	PPoint q=CreatePCB();
	char show[2*PCBCOUNT][2*MAXTIME];
	int counter=0,i,j;
	for(i=0;i<2*PCBCOUNT;i++)
		for(j=0;j<2*MAXTIME;j++)
		show[i][j]=' ';
	printf("---------------RR算法执行中----------------\n");
	while(head->next!=NULL)
	{
		PPoint temp;
		p=head->next;
		show[p->PID-1][counter]='-';
		counter++;
		if(p->nTime>5)
		{
			p->nTime-=5;
		}
		else
		{
			deleteP(head,p);
			schedule(head,q);
			continue;
		}
		temp=p;
		head->next=p->next;
		while(p->next!=NULL)p=p->next;
		p->next=temp;
		temp->next=NULL;
	}
	printf("---------------算法运行序列----------------\n");
	for(i=2*PCBCOUNT;i>0;i--)
	{	printf("%d",i);
		for(j=0;j<counter;j++)
		printf("%c",show[i-1][j]);
		printf("\n");
	}
} 
void menu()//菜单 
{
	int choice=-1; 
	printf("-----------请选择算法------------\n");
	printf("0.SRTF,最短剩余时间优先算法\n");
	printf("1.FCFS,先来先服务算法\n");
	printf("2.RR,时间片轮转算法\n");
	printf("输入其它不在选项的值将退出程序\n"); 
	scanf("%d",&choice);
	switch(choice)
	{
		case 0:SRTF();break;
		case 1:FCFS();break;
		case 2:RR();break;
		default:return;
	}
	menu();
}
int main()
{
	menu(); 
	return 0;
}

数据结构还不算太复杂,但是个人水平有限只能些这样的了。

具体细节大家自行查阅,如有不懂可评论留言。

以下是程序截图:

欢迎大家讨论并指出其中的不足。

猜你喜欢

转载自blog.csdn.net/ZC_25/article/details/78500904