#include <stdio.h>
#include <stdlib.h>
#include <time.h> //生成随机磁盘访问序列时用到
#include <string.h>
#include <malloc.h> //动态分配空间
#include <unistd.h>
#define N 10
//进程控制
//进程控制块
struct PCB{
int id;
int PID;
struct PCB *next;
};
struct PCB *running; //定义指针变量running,指向结构体执行的PCB
struct PCB *ready; //定义指针变量running,指向结构体就绪的PCB
struct PCB *blocked; //定义指针变量running,指向结构体阻塞的PCB
struct PCB *q;
struct PCB *p;
int id=0; //进程序号
int PID; //定义进程创建函数createProcess()时用到的PID
//设备
struct DCT{
char name[10];
int busy;
struct PCB *occupied; //指向占用设备的进程
struct PCB *waiting; //指向设备的等待队列
struct DCT *next;
struct COCT *coct; //设备的上级控制器
};
struct DCT *dcts; //定义指针变量dcts,指向结构体类型变量DCT
//控制器
struct COCT{
char name[10];
int busy;
struct PCB *occupied;
struct PCB *waiting;
struct COCT *next;
struct CHCT *chct; //控制器的上级通道
};
struct COCT *cocts; //定义指针变量cocts,指向结构体类型变量COCT
//通道
struct CHCT{
char name[10];
int busy;
struct PCB *occupied;
struct PCB *waiting;
struct CHCT *next;
};
struct CHCT *chcts; //定义指针变量chcts,指向结构体类型变量CHCT
void menu();
//进程进入队列(就绪队列、阻塞队列)
void enqueue(int id,int PID,struct PCB *head){
//由系统生成一个PCB型的结点,同时将该结点的起始位置赋给指针变量node
struct PCB *node=(struct PCB *)malloc(sizeof(struct PCB));
node->next=0;
node->id=id;
node->PID=PID;
struct PCB *tmp=head;
while(tmp->next!=0)
tmp=tmp->next;
tmp->next=node;
}
//进程移出队列
struct PCB *dequeue(struct PCB *head){
struct PCB *tmp=head->next;
if(head->next!=0){
head->next=head->next->next;
tmp->next=0;
}
return(tmp);
}
//创建进程
void createProcess(){
int r;
printf("输入进程PID:\n");
scanf("%d",&r);
if(r!=0){
printf("进程创建成功");
PID=r;
printf("\n");
enqueue(id++,PID,ready); //用进队函数将进程放入就绪队列
if(running==0){ //如果没有正在执行的进程,则将等待队列中就绪进程调入执行
running=dequeue(ready);
}
}
}
//显示进程状态
void displayProcessstatus(){
printf("--------就绪状态--------\n");
if(ready->next==0)
printf("当前没有进程在该状态\n");
if(ready->next!=0)
{
q=ready->next;
while(ready->next!=0)
{
printf("%d\n",ready->next->PID);
ready->next=ready->next->next;
}
ready->next=q;
}
printf("--------执行状态--------\n");
if(running==0) printf("当前没有进程在该状态\n");
if(running!=0)
{
printf("%d\n",running->PID);
}
printf("--------阻塞状态--------\n");
if(blocked->next==0) printf("当前没有进程在该状态\n\n");
if(blocked->next!=0)
{
p=blocked->next;
while(blocked->next!=0)
{
printf("%d\n",blocked->next->PID);
blocked->next = blocked->next->next;
}
blocked->next=p;
}
}
/**********************设备分配*********************/
//设备分配时用设备名找到要添加的设备
struct DCT *findDCT(char name[])
{
struct DCT *temp = dcts; //定义指针temp指向设备队列头指针
while(temp->next!=NULL)
{
temp = temp->next;
if(strcmp(temp->name,name)==0)
return temp;
}
return NULL;
}
//用通道名查找通道
struct CHCT *findChannel(char name[])
{
struct CHCT *temp = chcts;
while(temp->next!=NULL)
{
temp = temp->next;
if(strcmp(temp->name,name)==0)
return temp;
}
return NULL;
}
//用控制器名查找控制器
struct COCT *findController(char name[])
{
struct COCT *temp = cocts;
while(temp->next!=NULL)
{
temp = temp->next;
if(strcmp(temp->name,name)==0)
return temp;
}
return NULL;
}
//如果存在占用将新建进程放入(设备、控制器、通道)等待队列队尾
void addProcesstoWaiting(struct PCB *waiting,struct PCB *p)
{
struct PCB *temp = waiting;
while(temp->next!=NULL)
{
temp = temp->next;
}
struct PCB *newnode=(struct PCB *)malloc(sizeof(struct PCB)); //建一个空的进程控制块,用来存放将要进入队列的进程
temp->next=newnode;
temp->next->id = p->id;
temp->next->PID=p->PID;
temp->next->next = NULL;
}
//进程入(running,ready,blocked)队列
void add(struct PCB *head,struct PCB *node){
struct PCB *tmp=head;
while(tmp->next!=0)
tmp=tmp->next;
tmp->next=node;
}
//分配通道
void allocateCHCT(struct CHCT *chct,struct PCB *p)
{
add(blocked,p);//将进程切换到阻塞队列
if(ready!=0)
running=dequeue(ready);
else
running=0;
if(chct->occupied!=0) //如果通道被占用
{
printf("不能分配通道\n");
addProcesstoWaiting(chct->waiting,p); //添加进程到通道等待队列
}
else
{
chct->occupied=p;
printf("分配成功!\n");
// add(blocked,p); //将进程切换到阻塞队列
}
}
//分配控制器
void allocateCOCT(struct COCT *coct,struct PCB *p)
{
if(coct->occupied!=0){
printf("不能分配控制器\n");
addProcesstoWaiting(coct->waiting,p);//添加进程到控制器等待队列
if(ready!=0)
running=dequeue(ready);
else
running=0;
allocateCHCT(coct->chct,p);//未分配控制器,添加进程到控制器等待队列的同时请求分配通道
}else{
coct->occupied=p;
allocateCHCT(coct->chct,p); //已分配控制器请求分配通道
}
}
//分配设备
void allocateDCT(){
char nameDCT[10];
printf("请输入设备名称:");
scanf("%s",nameDCT);
struct DCT * dct=findDCT(nameDCT);
struct PCB * p = running;
if(dct!=NULL&&p!=NULL)
{
if(dct->occupied!=0){
printf("不能分配设备\n");
addProcesstoWaiting(dct->waiting,p);
add(blocked,p);
if(ready!=0)
running=dequeue(ready);
else
running=0;
return;
}else{
dct->occupied=p;
allocateCOCT(dct->coct,p); //设备分配成功请求分配控制器
}
}
else printf(dct == NULL ? "设备不存在!\n" : "出现错误!\n");
}
//释放通道
void releaseCHCT(int PID,struct CHCT *chct,struct PCB *p)
{
if(chct->occupied->PID==PID)
{
if(chct->waiting->next!=NULL)
{
chct->occupied = dequeue(chct->waiting);
}
else
{
chct->occupied = NULL;
}
}
}
//释放控制器
void releaseCOCT(int PID,struct COCT *coct,struct PCB *p)
{
if(coct->occupied->PID==PID)
{
if(coct->waiting->next!=NULL)
{
coct->occupied = dequeue(coct->waiting);
}
else
{
coct->occupied = NULL;
}
releaseCHCT(PID,coct->chct,coct->occupied); //控制器已释放,请求释放通道
}
}
//释放设备
void releaseDCT()
{
char nameDCT[10];
printf("请输入要释放的设备名称:\n");
scanf("%s",nameDCT);
int P;
struct DCT *temp = findDCT(nameDCT);
printf("请输入要释放的进程PID:\n");
scanf("%d",&temp->occupied->PID);
if(temp->occupied->PID!=0)
{
if(temp->waiting->next!=NULL)
{
temp->occupied = dequeue(temp->waiting);
}
else
{
temp->occupied = NULL;
}
releaseCOCT(P,temp->coct,temp->occupied); //设备释放成功,请求释放控制器
}
else
{
printf("没有对应的设备和进程!");
}
}
//+++++++++++++++++++++设备添加操作+++++++++++++++
//增加通道
void addChannel(char name[]){
struct CHCT *temp=(struct CHCT *)malloc(sizeof(struct CHCT));//开辟内存空间
strcpy(temp->name,name);
temp->next=0;
temp->busy=0;
struct PCB *newnode=(struct PCB *)malloc(sizeof(struct PCB));
temp->waiting=newnode;
temp->waiting->next = NULL;
temp->occupied=0;
struct CHCT * head=chcts; //进入了chcts队列
while(head->next!=0)
head=head->next;
head->next=temp;
}
//增加控制器
void addController(char *name,struct CHCT *chct){
struct COCT *temp=(struct COCT *)malloc(sizeof(struct COCT));
strcpy(temp->name,name);
temp->next=0;
temp->busy=0;
struct PCB *newnode=(struct PCB *)malloc(sizeof(struct PCB));
temp->waiting=newnode;
temp->waiting->next = NULL;
temp->occupied=0;
temp->chct= chct;
struct COCT *head=cocts; //进入了cocts队列
while(head->next!=0)
head=head->next;
head->next=temp;
}
//增加设备
void addDevice(char *name,struct COCT *coct){ //增加设备
struct DCT *temp=(struct DCT *)malloc(sizeof(struct DCT));
strcpy(temp->name,name);
temp->next=0;
temp->busy=0;
struct PCB *newnode=(struct PCB *)malloc(sizeof(struct PCB));
temp->waiting=newnode;
temp->waiting->next = NULL;
temp->occupied=0;
temp->coct= coct;
struct DCT *head=dcts;
while(head->next!=0)
head=head->next;
head->next=temp;
}
//添加设备
void add_dct(){
char newDCT[10];
printf("请输入新设备的名字:\n");
scanf("%s",newDCT);
char newCOCT[10];
printf("请输入要添加到的控制器的名字:\n");
scanf("%s",newCOCT);
addDevice(newDCT,findController(newCOCT)); //请求增加设备程序
}
//添加控制器
void add_coct(){
char newCOCT[10];
printf("请输入新控制器的名字:\n");
scanf("%s",newCOCT);
char newCHCT[10];
printf("请输入要添加到的通道的名字:\n");
scanf("%s",newCHCT);
addController(newCOCT,findChannel(newCHCT)); //请求增加控制器程序
}
//添加通道
void add_chct(){
char newCHCT[10];
printf("请输入新的通道的名字:\n");
scanf("%s",newCHCT);
addChannel(newCHCT); //请求增加通道程序
}
//+++++++++++++++++删除操作++++++++++++++++++++
//删除设备
void deleteDCT(char nameDCT[]){
struct DCT *temp = findDCT(nameDCT);
struct DCT *head = dcts;
if(temp==NULL){
printf("没有对应的设备!\n");
return ;
}
else
while(head->next!=0)
{
if(strcmp(temp->name,head->next->name)==0)
{
if(temp->occupied!=NULL)
printf("此设备现在正在使用不能删除\n");
else
head->next=head->next->next;
break;
}
else
head=head->next;
}
}
//删除控制器
void deleteCOCT(char nameCOCT[]){
struct COCT *temp=findController(nameCOCT);
struct COCT *head=cocts;
if(temp==NULL){
printf("没有对应的控制器\n");
return;
}
else
while(head->next!=0)
{
if(strcmp(temp->name,head->next->name)==0){
if(temp->occupied!=NULL)
printf("此控制器现在正在使用不能删除\n");
else{
// deleteDCT(temp->);
head->next=head->next->next;
}
break;
}
head=head->next;
}
}
//删除通道
void deleteCHCT(char nameCHCT[]){
struct CHCT *temp=findChannel(nameCHCT);
struct CHCT *head=chcts;
if(temp==NULL){
printf("没有对应的通道\n");
return;
}
else
while(head->next!=0)
{
if(strcmp(temp->name,head->next->name)==0){
if(temp->occupied!=NULL)
printf("此通道现在正在使用不能删除\n");
else{
// deleteDCT(temp->);
head->next=head->next->next;
}
//i++;
break;
}
head=head->next;
}
}
//++++++++++++++++++++显示设备+++++++++++++++++++++++
void displayDCT()
{
struct DCT *dct;
struct COCT *coct;
struct CHCT *chct = chcts;
struct PCB *pcb;
//-----------------------------------------------------
while(chct->next!=NULL)
{
chct = chct->next;
printf(" %s(",chct->name);
if(chct->occupied!=0){
printf("%d",chct->occupied->PID);
}
printf(")");
pcb = chct->waiting->next; //waiting是头结点,pcb指向队列第一个进程
while(pcb!=NULL)
{
printf("[%d]",pcb->PID);
pcb = pcb->next;
}
printf("\n");
coct = cocts;
while(coct->next!=NULL)
{
coct = coct->next;
if(strcmp(coct->chct->name,chct->name)==0)
{
printf(" %s(",coct->name);
if(coct->occupied!=0)
printf("%d",coct->occupied->PID);
printf(")");
pcb = coct->waiting->next;
while(pcb!=NULL)
{
printf("[%d]",pcb->PID);
pcb = pcb->next;
}
printf("\n");
//-----------------------------------------
dct = dcts;
while(dct->next!=NULL)
{
dct = dct->next;
if(strcmp(dct->coct->name,coct->name)==0)
{
printf(" %s(",dct->name);
if(dct->occupied!=0)
printf("%d",dct->occupied->PID);
printf(")");
pcb = dct->waiting->next;
while(pcb!=NULL)
{
printf("[%d]",pcb->PID);
pcb = pcb->next;
}
printf("\n");
}
}
}
}
}
}
//冒泡排序算法,从小到大排序
void Sort(int Array[],int n)
{
int i,j,temp;
for(i=1;i<n;i++)
for(j=0;j<n-i;j++)
if(Array[j]>Array[j+1]){
temp=Array[j];
Array[j]=Array[j+1];
Array[j+1]=temp;
}
}
//输出磁道请求顺序
void Output(int Track[],int Num,int m)
{
int i;
printf("请求的磁道序列为:");
for(i=0;i<m;i++){
printf(" %d ",Track[i]);
}
printf("\n");
printf("当前所在磁道号是:%d\n",Num);
}
/*********************先来先服务调度算法**************************/
void FCFS(int Track[],int Num ,int m)
{
int i,temp;
int Sum=0; //总寻道长度
float AverTime=0.0; //平均寻道长度
printf("*************先来先服务调度算法*******************\n\n");
Output(Track,Num,m);
for(i=0;i<m;i++)
{
if(Num<Track[i])
temp=Track[i]-Num;
else temp=Num-Track[i];
Num=Track[i];
Sum+=temp;
}
AverTime=(float)Sum/m;
printf("磁道访问的序列为:");
for(i=0;i<m;i++)
printf(" %d ",Track[i]);
printf("\n平均寻道长度为:%.2f\n\n",AverTime);
}
/**********************循环扫描调度算法*****************************/
void C_SCAN(int Track[],int Num, int m)
{
int i,j,k=0,r=0,l=0;
int temp[m];
int Sum=0;
float AverTime=0.0;
printf("**************循环扫描调度算法********************\n\n");
Output(Track,Num,m);
for(i=0;i<m;i++)
temp[i]=Track[i];
Sort(temp,m);
printf("磁道访问的序列为:");
while(temp[k]<Num){
k++;
}
l=k-1;
r=k;
for(j=r;j<m;j++){
printf(" %d ",temp[j]);
}
for(j=0;j<r;j++){
printf(" %d ",temp[j]);
}
Sum=2*temp[m-1]+temp[l]-Num-2*temp[0];
AverTime=(float)(Sum)/(float)(m);
printf("\n平均寻道长度为:%.2f\n\n",AverTime);
}
/**********************最短寻道时间优先调度算法********************/
void SSTF(int Track[],int Num,int m)
{
int i,j,Ttrack[m],Disk[m];
int min,minj,Dcount=0;
int Sum=0;
float AverTime=0.0;
printf("***************最短寻道时间优先调度算法***********\n\n");
Output(Track,Num,m);
for(i=0;i<m;i++){
Ttrack[i]=0;
}
for(j=0;j<m;j++){
for(i=0;i<m;i++){
if(Ttrack[i]==-1)
continue;
else{
if(Num<Track[i])
Ttrack[i]=Track[i]-Num;
else Ttrack[i]=Num-Track[i];
}
}
min=200;
minj=0;
for(i=0;i<m;i++){
if(Ttrack[i]==-1) continue;
else{
if(Ttrack[i]<min){
min=Ttrack[i];
minj=i;
}
}
}
Num=Track[minj];
Disk[Dcount++]=Num;
Sum=Sum+Ttrack[minj];
Ttrack[minj]=-1;
}
AverTime=(float)Sum/m;
printf("磁道访问的序列为:");
for(i=0;i<m;i++)
printf(" %d ",Disk[i]);
printf("\n平均寻道长度为:%.2f\n\n",AverTime);
}
/***********************扫描调度算法*******************************/
void SCAN(int Track[],int Num ,int m)
{
int i,j,k=0,r=0,l=0,choose;
int temp[m];
int Sum=0;
float AverTime=0.0;
printf("**************扫描调度算法************************\n\n");
Output(Track,Num,m);
for(i=0;i<m;i++)
temp[i]=Track[i];
Sort(temp,m); //将访问序列从小到大排序
while(temp[k]<Num) //找到Num在访问序列所在的位置
{
k++;
}
l=k-1;
r=k;
printf("请输入移动臂移动方向 (1 表示比当前磁道号大的方向 ,0表示比当前磁道小的方向) : ");
scanf("%d",&choose);
if(choose==0){
printf("磁道访问的序列为:");
for(j=l;j>=0;j--){
printf(" %d ",temp[j]);
}
for(j=r;j<m;j++){
printf(" %d ",temp[j]);
}
Sum=Num-2*temp[0]+temp[m-1];
}
else{
printf("磁道访问的序列为:");
for(j=r;j<m;j++)
{
printf(" %d ",temp[j]);
}
for(j=l;j>=0;j--)
{
printf(" %d ",temp[j]);
}
Sum=Num-temp[0]+2*temp[m-1];
}
AverTime=(float)Sum/m;
printf("\n平均寻道长度为:%.2f\n\n",AverTime);
}
void managePCB(){
while(1)
{
int choice;
printf("********************************************************\n");
printf("************* 进程管理 ***********\n");
printf("********************************************************\n");
printf("************* 请选择 ***********\n");
printf("********** ********\n");
printf("***** 1:创建进程 *****\n");
printf("***** 2:显示进程 *****\n");
printf("***** 0:返回主菜单 *****\n");
printf("******************************************************\n\n");
printf("请输入:");
scanf("%d",&choice);
switch(choice)
{
case 1:createProcess();displayProcessstatus();break;
case 2:displayProcessstatus();break;
case 0:menu();break;
}
}
}
void manageDCT(){
char nameDCT[10];
char nameCOCT[10];
char nameCHCT[10];
int function;
while(1)
{
printf("********************************************************\n");
printf("************* 设备管理 ***********\n");
printf("********************************************************\n");
printf("************* 请选择 ***********\n");
printf("********** ********\n");
printf("***** 1:设备分配 *****\n");
printf("***** 2:设备释放 *****\n");
printf("***** 3:显示设备 *****\n");
printf("***** 4:添加设备 *****\n");
printf("***** 5:添加控制器 *****\n");
printf("***** 6:添加通道 *****\n");
printf("***** 7:删除设备 *****\n");
printf("***** 8:删除控制器 *****\n");
printf("***** 9:删除通道 *****\n");
printf("***** 0:返回主界面 *****\n");
printf("***** *****\n");
printf("******************************************************\n\n");
printf("请输入:");
scanf("%d",&function);
switch(function)
{
case 1:allocateDCT();displayDCT();break;
case 2:releaseDCT();displayDCT();break;
case 3:displayDCT();break;
case 4:add_dct();displayDCT();break;
case 5:add_coct();displayDCT();break;
case 6:add_chct();displayDCT();break;
case 7:
printf("请输入要删除DCT的名字:\n");
scanf("%s",nameDCT);
deleteDCT(nameDCT);displayDCT();break;
case 8:
printf("请输入要删除COCT的名字:\n");
scanf("%s",nameCOCT);
deleteCOCT(nameCOCT);displayDCT();break;
case 9:
printf("请输入要删除CHCT的名字:\n");
scanf("%s",nameCHCT);
deleteCHCT(nameCHCT);displayDCT();break;
case 0:menu();break;
}
}
}
void manageDisk(){
//磁盘调度相关定义
int Input,i,num,j;
printf("请求的磁道访问序列的长度:\n");
scanf("%d",&j);
int Track[j]; //存放输入的
printf("请输入磁道访问序列(序列长度为%d):\n",j);
for(i=0;i<j;i++){
scanf("%d",&Track[i]);
}
printf("请输入当前磁道号:\n");
scanf("%d",&num);
while(1){
printf("*****************************************************\n");
printf("************* 磁盘调度算法 **********\n");
printf("*****************************************************\n");
printf("************* 请选择要使用的算法 *********\n");
printf("********** *****\n");
printf("***** 1、先来先服务调度算法(FCFS) *****\n");
printf("***** 2、最短寻道时间优先调度算法(SSTF) *****\n");
printf("***** 3、扫描调度算法(SCAN) *****\n");
printf("***** 4、循环扫描调度算法(CSCAN) *****\n");
printf("***** 5、调用四种算法,进行比较 *****\n");
printf("***** 6、返回主界面 *****\n");
printf("******************************************************\n\n");
printf("请选择算法:");
scanf("%d",&Input);
printf("\n");
switch(Input)
{
case 1: //使用FCFS算法
FCFS(Track,num,j);break;
case 2: //使用SSTF算法
SSTF(Track,num,j); break;
case 3: //使用SCAN算法
SCAN(Track,num,j);break;
case 4: //使用CSCAN算法
C_SCAN(Track,num,j);break;
case 5:
FCFS(Track,num,j);
SSTF(Track,num,j);
SCAN(Track,num,j);
C_SCAN(Track,num,j);break;
case 6:menu(); break;
}
}
}
void menu(){
while(1)
{
int choice;
printf("********************************************************\n");
printf("************* 主菜单 ***********\n");
printf("********************************************************\n");
printf("************* 请选择 ***********\n");
printf("********** ********\n");
printf("***** 1:进程管理 *****\n");
printf("***** 2:设备管理 *****\n");
printf("***** 3:磁盘调度 *****\n");
printf("***** 0:退出系统 *****\n");
printf("******************************************************\n\n");
printf("请输入:");
scanf("%d",&choice);
switch(choice)
{
case 1:managePCB();break;
case 2:manageDCT();break;
case 3:manageDisk();break;
case 0:exit(0);
}
}
}
int main(){
ready=(struct PCB *)malloc(sizeof(struct PCB));
blocked=(struct PCB *)malloc(sizeof(struct PCB));
ready->next=0;
blocked->next=0;
//设备分配相关定义
dcts=(struct DCT *)malloc(sizeof(struct DCT));
dcts->next=0;
cocts=(struct COCT *)malloc(sizeof(struct COCT));
cocts->next=0;
chcts=(struct CHCT *)malloc(sizeof(struct CHCT));
chcts->next=0;
//添加设备
addChannel("chct1");
addChannel("chct2");
addController("coct1",findChannel("chct1"));
addController("coct2",findChannel("chct1"));
addController("coct3",findChannel("chct2"));
addDevice("input1",findController("coct1"));
addDevice("printer1",findController("coct1"));
addDevice("input2",findController("coct2"));
addDevice("printer2",findController("coct2"));
addDevice("disk1",findController("coct3"));
menu();
return 0;
}