排他的な機器割り当て関連の概念
ラボ環境
実験の前提条件
システムに4種類の機器がある場合、各タイプに1つずつ、3つの機器コントローラー、機器コントローラーを追加できます。システムに既に存在する機器を追加する場合、機器コントローラーを追加する必要はありませんが、システムに存在しない機器を追加します。機器の場合、新しい機器コントローラー(2チャネル)を手動で追加する必要があります。機器、機器コントローラー、およびチャネルが同時に正常に適用された場合にのみ、機器を正常に割り当てることができます。この実験では、チャネルを追加できません。
実験関連コード
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
typedef struct pcb/*进程*/
{
int pcbID; /*进程名称*/
struct pcb *next;
}PCB;
typedef struct chct//通道控制表
{
int chctID;
int status;//设备状态
PCB *block;//阻塞队列
}CHCT;
typedef struct coct//控制器控制表
{
int coctID;
int status;//设备状态
CHCT *chct;//控制器所连接的通道
PCB *block;//阻塞队列
struct coct *next;//控制器队列
}COCT;
typedef struct dct//设备控制表
{
int dctID;
int status;//设备状态
int processid;//占用进程ID
PCB *block;//阻塞队列指针
COCT *coct;//与设备控制器相关连的控制器控制表
struct dct* next;//同类设备的不同设备
}DCT;
typedef struct sdt//系统设备表
{
char type;//系统设备表类型
char name[MAX];//系统设备表名称
DCT *dct;//DCT设备控制表
struct sdt *next;//驱动入口地址
}SDT;
/*设置全局变量 2个通道、3个设备控制器、4个设备*/
CHCT *CH1,*CH2;//两个通道ch1,ch2
COCT *coct_head;//控制器控制表头部
SDT *sdt_head;
void init()
{
PCB *ch1pcbblock,*ch2pcbblock,*co1pcbblock,
*co2pcbblock,*co3pcbblock,
*d1pcbblock,*d2pcbblock,
*d3pcbblock,*d4pcbblock;//各个设备的等待队列
COCT*CO1,*CO2,*CO3;
DCT *dct1,*dct2,*dct3,*dct4;
SDT *sdt1,*sdt2,*sdt3,*sdt4;
CH1=(CHCT*)malloc(sizeof(CHCT));
CH2=(CHCT*)malloc(sizeof(CHCT));
CH1->status=0;
CH2->status=0;
CH1->chctID = 1;
CH2->chctID = 2;
ch1pcbblock=(PCB*)malloc(sizeof(PCB));
ch2pcbblock=(PCB*)malloc(sizeof(PCB));
ch1pcbblock->next=NULL;
ch2pcbblock->next=NULL;
CH1->block=ch1pcbblock;
CH2->block=ch2pcbblock;
coct_head=(COCT*)malloc(sizeof(COCT));
coct_head->next=NULL;
CO1=(COCT*)malloc(sizeof(COCT));
CO2=(COCT*)malloc(sizeof(COCT));
CO3=(COCT*)malloc(sizeof(COCT));
CO1->status=0;
CO2->status=0;
CO3->status=0;
coct_head->next=CO1;
CO1->next=CO2;
CO2->next=CO3;
CO3->next=NULL;
co1pcbblock=(PCB *)malloc(sizeof(PCB));
co1pcbblock->next=NULL;
co2pcbblock=(PCB *)malloc(sizeof(PCB));
co2pcbblock->next=NULL;
co3pcbblock=(PCB *)malloc(sizeof(PCB));
co3pcbblock->next=NULL;
CO1->coctID = 1;
CO2->coctID = 2;
CO3->coctID = 3;
//随机分配起始时的通道和控制的连接情况
CO1->chct=CH1;
CO2->chct=CH1;
CO3->chct=CH2;
CO1->block=co1pcbblock;
CO2->block=co2pcbblock;
CO3->block=co3pcbblock;
d1pcbblock=(PCB *)malloc(sizeof(PCB));
d2pcbblock=(PCB *)malloc(sizeof(PCB));
d3pcbblock=(PCB *)malloc(sizeof(PCB));
d4pcbblock=(PCB *)malloc(sizeof(PCB));
d1pcbblock->next=NULL;
d2pcbblock->next=NULL;
d3pcbblock->next=NULL;
d3pcbblock->next=NULL;
dct1=(DCT *)malloc(sizeof(DCT));
dct2=(DCT *)malloc(sizeof(DCT));
dct3=(DCT *)malloc(sizeof(DCT));
dct4=(DCT *)malloc(sizeof(DCT));
dct1->dctID = 1;
dct2->dctID = 1;
dct3->dctID = 1;
dct4->dctID = 1;
dct1->coct=CO1;
dct2->coct=CO2;
dct3->coct=CO3;
dct4->coct=CO3;
dct1->status=0;
dct2->status=0;
dct3->status=0;
dct4->status=0;
//同类设备链表
dct1->next = NULL;
dct2->next = NULL;
dct3->next = NULL;
dct4->next = NULL;
dct1->block=d1pcbblock;
dct2->block=d2pcbblock;
dct3->block=d3pcbblock;
dct4->block=d4pcbblock;
sdt_head=(SDT *)malloc(sizeof(SDT));
sdt_head->next=NULL;
sdt1=(SDT *)malloc(sizeof(SDT));
sdt2=(SDT *)malloc(sizeof(SDT));
sdt3=(SDT *)malloc(sizeof(SDT));
sdt4=(SDT *)malloc(sizeof(SDT));
sdt_head->next=sdt1;
sdt1->next=sdt2;
sdt2->next=sdt3;
sdt3->next=sdt4;
sdt4->next = NULL;
strcpy(sdt1->name,"printer");
strcpy(sdt2->name,"screen");
strcpy(sdt3->name,"keyboad");
strcpy(sdt4->name,"mouse");
sdt1->dct=dct1;
sdt2->dct=dct2;
sdt3->dct=dct3;
sdt4->dct=dct4;
}
/**
遍历sdt表,找到相应的设备类
*/
SDT* TravseSDT(char searchname[]){
SDT* tmp;
tmp = sdt_head->next;
while(tmp!=NULL){
// printf("%s\n",tmp->name);
if(strcmp(tmp->name,searchname) == 0){
printf("a:%s\n",tmp->name);
return tmp;
}
tmp = tmp->next;
}
return sdt_head;
}
/**
显示所有的设备及状态
*/
void display(){
SDT* sdttmp = sdt_head->next;
DCT* dcttmp = NULL;
printf("SDT 设备ID 设备状态 所连COCT的ID COCT状态 所连CHCT的ID CHCT状态\n");
while(sdttmp != NULL){
dcttmp = sdttmp->dct;
while(dcttmp != NULL){
printf("%s\t%d\t%d %d %d %d %d\n",sdttmp->name,dcttmp->dctID,dcttmp->status,dcttmp->coct->coctID,dcttmp->coct->status,dcttmp->coct->chct->chctID,dcttmp->coct->chct->status);
dcttmp = dcttmp->next;
}
sdttmp = sdttmp->next;
}
}
/**
void displaySDT(){
SDT* p = sdt_head->next;
while(p!=NULL){
printf("%s\n",p->name);
p = p->next;
}
}
*/
/**
添加设备
*/
void addDevice(){
int channelid;//通道号
printf("请输入待添加设备的名称\n");
char devicename[30];
scanf("%s",devicename);
SDT* cur = TravseSDT(devicename);
DCT* pt = cur->dct;
if(cur != sdt_head){//添加已知种类的设备
while(pt->next!=NULL){
pt=pt->next;
}
DCT* p = (DCT*)malloc(sizeof(DCT));
pt->next = p;
p->next = NULL;
printf("请输入待添加设备的标识\n");
scanf("%d",&p->dctID);
p->status = 0;
p->block = (PCB*)malloc(sizeof(PCB));
p->coct = cur->dct->coct;
}else{//添加新的种类的设备
SDT* newsdt = (SDT*)malloc(sizeof(SDT));
newsdt->next= sdt_head->next;
sdt_head->next = newsdt;
DCT* newdct = (DCT*)malloc(sizeof(SDT));
newdct->dctID = 1;
newdct->status=0;
strcpy(newsdt->name,devicename);
newsdt->dct=newdct;
newdct->next = NULL;
printf("请输入要添加设备控制器的信息\n");
COCT* con = (COCT*)malloc(sizeof(COCT));
newdct->coct = con;
con->next = coct_head->next;
coct_head->next = con;
printf("请输入控制器的标识\n");
scanf("%d",&con->coctID);
con->status=0;
printf("请输入要使用的通道号\n");
scanf("%d",&channelid);
if(channelid == 1){
con->chct = CH1;
}
if(channelid == 2){
con->chct = CH2;
}
con->block = (PCB*)malloc(sizeof(PCB));
}
}
/**
删除设备
*/
void deleteDevice(){
printf("请输入要删除的设备的种类名称\n");
char deletename[30];
scanf("%s",deletename);
SDT* tmp = TravseSDT(deletename);//找到该类设备的sdt
int i =1;
if(tmp!=sdt_head){
printf("请输入要删除设备的ID\n");
int deleteid;
scanf("%d",&deleteid);
DCT* cur = tmp->dct;
while(cur != NULL){
if(cur->dctID == deleteid && i==1){//删除找到的设备ID,删除第一个节点
tmp->dct = cur->next;
break;
}else if(cur->next->dctID == deleteid && cur->next->next != NULL){//中间节点
DCT* p = cur->next;
p->coct = NULL;
cur->next = cur->next->next;
free(p);
break;
}else if(cur->next->dctID == deleteid && cur->next->next == NULL){//最后一个节点
cur->next = NULL;
}
cur = cur->next;
i++;
}
}else{
printf("该类设备不存在\n");
}
}
/**
分配设备
*/
void allotDevice(){
PCB* pro = (PCB*)malloc(sizeof(PCB));
printf("输入进程标识\n");
scanf("%d",&pro->pcbID);
pro->next = NULL;
printf("请输入要申请的设备种类名称\n");
char name[30];
scanf("%s",name);
//判断所有该类设备是否有空闲的
SDT* p = sdt_head->next;
DCT* pt = NULL;
int flag=0;
while(p!=NULL){
if(strcmp(p->name,name) == 0){//找到该类设备
pt = p->dct;
while(pt!=NULL){
if(pt->status == 0){//设备可用
pt->status =1;
flag = 1;
break;
}
pt = pt->next;
}
if(flag==1){
if(pt->coct->status == 0){//该类设备对应的设备控制器可用
pt->coct->status = 1;
if(pt->coct->chct->status == 0){//相应的通道可用
pt->coct->chct->status =1;
printf("设备分配成功\n");
}else{//进入相应的通道等待队列
printf("通道忙碌\n");
PCB* newpcb = (PCB*)malloc(sizeof(PCB));
newpcb->next = pt->coct->chct->block->next;
pt->coct->chct->block->next = newpcb;
}
}else{//进入该设备相应的设备控制器等待队列
printf("设备控制器忙碌\n");
PCB* newpcb = (PCB*)malloc(sizeof(PCB));
newpcb->next = pt->coct->block->next;
pt->coct->block->next = newpcb;
}
}else{//进入设备等待队列
printf("设备忙碌\n");
PCB* newpcb = (PCB*)malloc(sizeof(PCB));
newpcb->next = pt->block->next;
pt->block->next = newpcb;
}
}
p = p->next;
}
}
/**
回收设备
*/
void reclaimDevice(){
printf("请输入要回收的设备种类\n");
char reclainname[30];
scanf("%s",reclainname);
int reclainID;//回收设备号
SDT* p = sdt_head->next;
DCT* pt = NULL;
while(p!=NULL){
if(strcmp(reclainname,p->name) == 0){//找到该类设备
printf("请输入要回收的设备ID\n");
scanf("%d",&reclainID);
pt = p->dct;
while(pt!=NULL){
if(pt->dctID == reclainID){
pt->status=0;
// pt->coct->status =0;
// pt->coct->chct->status = 0;
}
pt=pt->next;
}
}
p = p->next;
}
}
int main()
{
//初始化
init();
display();
int NUM;
while(1){
printf("----选项----\n");
printf("NUM = 1:添加设备\n");
printf("NUM = 2:删除设备\n");
printf("NUM = 3:分配设备\n");
printf("NUM = 4:回收设备\n");
printf("请输入NUM:");
scanf("%d",&NUM);
if(NUM == 1){
addDevice();
display();
}else if(NUM == 2){
deleteDevice();
display();
}else if(NUM == 3){
allotDevice();
display();
}else{
reclaimDevice();
display();
}
}
return 0;
}