操作系统实验三

设备管理

●基本要求:在前面的实验基础上实现设备管理功能的模拟,主要包括通道和控制器的添加和删除,设备的添加、删除,设备的分配和回收。
●实验提示:
1、假定模拟系统中已有键盘、鼠标、打印机和显示器四个设备,另有三个控制器和两个通道。
2、设备管理子系统涉及到系统设备表(SDT)、通道控制表(CHCT)、控制器控制表(COCT)和设备控制表(DCT)来体现输入输出系统的四级结构和三级控制。应实现上述数据结构来完成对外围设备的管理。
数据结构参考代码:
C/C++版:
struct Node{
char name[10]; //名称
struct PCB *process; //占用该节点的进程
struct PCB *waitinglist; //等待该节点的进程队列
struct Node *next; //下一个节点
struct Node *parent; //父节点
};
struct Node *CHCTs; //通道队列头节点
struct Node *COCTs; //控制器队列头节点
struct Node *DCTs; //设备队列头节点
Java版:
class IONode{
String name;
IONode next;
Process process;
Vector waitinglist;
IONode parent;
}
class CHCT extends IONode{}
class COCT extends IONode{}
class DCT extends IONode{}
3、实现上述设备、控制器以及通道的层次关系,同时能够添加或删除新的设备、控制器或通道。
4、通过键盘命令模拟进程执行过程中提出的设备分配或释放请求,并为此请求分配或释放设备。分配设备成功后可将进程状态调整为阻塞,释放设备后变为就绪状态。
5、分配设备时应如果该设备已被其它进程占用,则设备分配失败,请求进程进入阻塞状态,同时等待该设备的释放。如果设备空闲,进程占用设备的同时还应提出申请控制器请求,直到与设备相关的通道都已申请成功为止。
6、设备、控制器或通道的释放应引起对应节点的等待队列中的第一个阻塞进程被唤醒。如果被唤醒的进程还未完成申请操作,应继续执行上级节点的申请操作。
7、回收流程:
8、*体现设备独立性,可以在设备分配时只指定设备类型,如果有空闲设备即可分配。
●评分标准(满分15分):
要求必须完成以下几个方面的内容(10-12分):
●在第1、2部分基础上扩展;
●能够模拟设备的分配与回收流程;
●设备分配成功与否,进程都应进入阻塞状态;
●能够较形象地输出通道、控制器、设备的层次关系以及进程的占用、等待状态;
也可实现如下扩充要求(3-5分):
●能够添加、删除通道、控制器或设备;
●能够模拟SDT基础上的设备分配过程。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
typedef struct PCB{
	char name[10];
	struct PCB *next;
}PCB,*PCBlist;
typedef struct Node{
     char name[10];
     PCBlist process;
     PCBlist waitting;//占用的进程,等待队列
     struct Node *next;
     struct Node *parent;
}Node,*Nodelist;
PCBlist running,ready,blocked;
Nodelist DCTS,COCTS,CHCTS;
PCBlist remove_process(PCBlist head,PCBlist p)//将进程p从队列head中移除
{
    PCBlist temp1=head;
    PCBlist temp2=head->next;
    while(temp1->next!=NULL)
        {
        if(temp2==p)
        {
            temp1->next=temp2->next;
            temp2->next=NULL;//把temp2从队列中删除
            return temp2;
        }
        temp1=temp2;
        temp2=temp2->next;
        }
    return NULL;
}
void display_pcb(PCBlist head)//展示进程
{
    PCBlist temp=head->next;
    while(temp!=NULL)
        {
        printf("%s ",temp->name);
        temp=temp->next;
        }
}
void display_waitting(Nodelist head)//展示设备的等待队列
{
    Nodelist temp=head->next;
    while(temp!=NULL)
        {
        display_pcb(temp->waitting);
        temp=temp->next;
        }
}
void addpcb(PCBlist head,PCBlist node)//添加进程
{
	if(node!=NULL)
        {
        PCBlist tmp=head;
		//PCBlist L=head->next;
		while(tmp->next!=NULL)
			tmp=tmp->next;
		tmp->next=node;
		node->next=NULL;
        }
}
PCBlist getFirstpcb(PCBlist head)//获取队列头
{
	if(head->next!=NULL)
        {
        PCBlist tmp=head->next;
		head->next=head->next->next;
		tmp->next=NULL;
		return tmp;
        }
	return NULL;
}
void create_process(char *name)//创建进程
{

	PCBlist p=new PCB;
    strcpy(p->name,name);
	addpcb(ready,p);//将创建的进程添加到就绪队列中
	if(running->next==NULL)//如果执行队列为空,则将就绪队列的队头变为执行队列
		running->next=getFirstpcb(ready);
}
void createNewProcess()
{
	char name[10];
	int size;
	printf("进程名称:");
	scanf("%s",name);
	create_process(name);
}
void timeout()//时间片到
{
	if(running->next!=NULL)
        {
		addpcb(ready,running->next);
		running->next=getFirstpcb(ready);
        }
}
void blockCurrentProcess()//执行进程被阻塞
{
    PCBlist tmp=getFirstpcb(running);
	if(tmp!=NULL)
        {
		addpcb(blocked,tmp);
		addpcb(running,getFirstpcb(ready));
        }
	else printf("当前执行进程为空!\n");
}
void wakeupBlockedProcess()//阻塞进程被唤醒
{
	PCBlist tmp=getFirstpcb(blocked);
	if(tmp!=NULL)
        {
		addpcb(ready,tmp);
		if(running->next==NULL)
            {
			addpcb(running,getFirstpcb(ready));
            }
        }
	else
        printf("当前没有被阻塞的进程!\n");
}
void terminateRunningProcess()//执行进程被终止
{
	int i,j;
    PCBlist tmp=running->next;
	if(tmp!=NULL)
        {
		running->next=NULL;
		addpcb(running,getFirstpcb(ready));
        }
	else
	printf("当前没有正在执行的进程!\n");
}
void display_process()//进程显示
{
    //PCBlist tmp=ready->next;
	printf("执行进程:");
	display_pcb(running);
	printf("\n就绪进程:");
	display_pcb(ready);
	printf("\n阻塞进程:");
	display_pcb(blocked);
	cout<<endl;
	display_waitting(CHCTS);
	display_waitting(COCTS);
	display_waitting(DCTS);
	printf("\n");
}
void block(PCBlist head,PCBlist p)//执行进程调用设备被阻塞          p为阻塞的进程,把p进程加入head队列
{

	if(p->next!=NULL)
        {
		addpcb(head,p->next);
		if(p==running)
            running->next=getFirstpcb(ready);
        }
	else
        printf("当前执行进程为空!\n");
}
int get_child_count( Nodelist node,Nodelist chile_head)//计算有多少个设备和node相连
{
    int count=0;
    Nodelist temp=chile_head->next;
    while(temp!=NULL)
        {
            if(temp->parent==node)
                count++;
            temp=temp->next;
        }
    return count;
}
 Nodelist FindByName(char *name, Nodelist node)//寻找设备在队列中的位置
{
    Nodelist temp=node->next;
    while(temp!=NULL)
        {
        if(strcmp(temp->name,name)==0)
            return temp;
        else
            temp=temp->next;
        }
    printf("错误!未找到%s\n",name);
    return NULL;
}
 Nodelist Add_Node(char *name,Nodelist parent, Nodelist head)//添加设备 name添加设备的名字,parent为此设备的父节点,head为设备所在的队列
{
    Nodelist temp=head;
    while(temp->next!=NULL)
        temp=temp->next;
    temp->next=new Node;
    strcpy(temp->next->name,name);
    temp->next->next=NULL;
    temp->next->parent=parent;
    temp->next->process=NULL;
	temp->next->waitting=new PCB ;
    temp->next->waitting->next=NULL;
    return temp->next;
}
void Delete_Node(char *name,Nodelist head)//删除设备,管理器,通道
{
     Nodelist temp1=head;
     Nodelist temp2=head->next;
    while(temp2!=NULL)
        {
            if(strcmp(temp2->name,name)==0)//在队列中找到设备
            {
                if(temp2->process==NULL && temp2->waitting->next==NULL)//如果没有进程占用此设备则删除
                {
                    temp1->next=temp2->next;
                }
                else
				{
					printf("错误!有进程正在占用,不可删除!%s\n",name);
				}
                return;
            }
            temp1=temp2;
            temp2=temp2->next;
        }
   
}
void Add_devices()//添加菜单
{
    int i;
    char name[10];
    char parent[10];
    while(1)
        {
        printf("1、添加设备\n");
        printf("2、添加控制器\n");
        printf("3、添加通道\n");
        printf("0、返回\n");
        scanf("%d",&i);
        if(i!=0)
        {
            printf("name:");
            scanf("%s",name);

        }
        if(i==1 || i==2)
            {
            printf("parent name:");
            scanf("%s",parent);
            }
        switch(i)
        {
        case 1:
            Add_Node(name,FindByName(parent,COCTS),DCTS);
            break;
        case 2:
            Add_Node(name,FindByName(parent,CHCTS),COCTS);
            break;
        case 3:
            Add_Node(name,NULL,CHCTS);
            break;
        case 0:
            return;
        }
    }
}
void Delete_devices()//删除菜单
{
    int i;
    char name[10];
    struct Node *temp;
    while(1)
        {
        printf("1、删除设备\n");
        printf("2、删除控制器\n");
        printf("3、删除通道\n");
        printf("0、返回\n");
        scanf("%d",&i);
        if(i!=0)
        {
            printf("name:");
            scanf("%s",name);

        }
        switch(i)
        {
        case 1:
            temp=FindByName(name,DCTS);
            if(temp==NULL)
                 printf("错误!未找到%s\n",name);
            else
                Delete_Node(name,DCTS);
            break;
        case 2:
            temp=FindByName(name,COCTS);
            if(temp==NULL)
                 printf("错误!未找到%s\n",name);
            else if(get_child_count(temp,DCTS)>0)//temp是控制器节点,此函数是查找temp的子节点DCTS设备节点的个数,如果有,则此处不可以删除该控制器节点
                printf("错误!不可删除%s\n",name);
            else
                Delete_Node(name,COCTS);
            break;
        case 3:
            temp=FindByName(name,CHCTS);
            if(temp==NULL)
                 printf("错误!未找到%s\n",name);
            else if(get_child_count(temp,COCTS)>0)//temp是控制器节点,此函数是查找temp的子节点DCTS设备节点的个数,如果有,则此处不可以删除该控制器节点
                printf("错误!不可删除%s\n",name);
            else
                Delete_Node(name,CHCTS);
            break;
        case 0:
            return;
        }
    }
}
void allocate_channel(Nodelist node, PCBlist p)//分配通道
{
    if(p->next==NULL)
        return;
    if(node->process==NULL)
        {
        node->process=p->next;
        block(blocked,p);//把执行进程添加到阻塞队列中
        }
    else
	{
		
        block(node->waitting,p);
	}
}
void allocate_controller(Nodelist node, PCBlist p)//分配控制器
{
    if(p->next==NULL)
        return ;
    if(node->process==NULL)
        {
            node->process=p->next;
            allocate_channel(node->parent,p);//给控制器对应的通道分配进程
        }
    else
	{
		PCBlist l=p->next;
		PCBlist t = node->waitting->next;
        block(node->waitting,p);//若控制器有进程占用,则将进程添加到此控制器的阻塞队列中
	}
}
void allocate_devices(Nodelist node, PCBlist p)//分配设备
{
    if(p->next==NULL)
        return ;
    if(node->process==NULL)
        {
            node->process=p->next;
            allocate_controller(node->parent,p);//给设备对应的控制器分配进程
        }
   else
   {
        block(node->waitting,p);//若设备被占用,则将进程添加到此设备的阻塞队列中
	}
}
void Allocate()//分配
{
    char name[10];
    Nodelist node;
    if(running->next==NULL)
        return;
    printf("device name:");
    scanf("%s",name);
    node=FindByName(name,DCTS);//在设备队列中找到要分配的设备
    if(node==NULL)
        return;
    else
        allocate_devices(node,running);
}
void release_channel(Nodelist node, PCBlist p)//释放通道
{
    if(node->process==p)
        {
        node->process=NULL;
        allocate_channel(node,node->waitting);//给等待队列中的第一个进程分配通道
        getFirstpcb(node->waitting);
        addpcb(ready,remove_process(blocked,p));//把释放的进程从阻塞队列中添加到就绪队列里
        if(running->next==NULL)
            running->next=getFirstpcb(ready);
        }
    else
    {
        addpcb(ready,remove_process(node->waitting,p));//把等待队列添加到就绪队列中
        if(running->next==NULL)
            running->next=getFirstpcb(ready);
    }
}
void release_controller(Nodelist node, PCBlist p)//释放控制器
{
    if(node->process==p)
        {
            node->process=NULL;
            allocate_controller(node,node->waitting);
            getFirstpcb(node->waitting);
            release_channel(node->parent,p);//释放控制器所对应的通道
        }
    else
    {
        addpcb(ready,remove_process(node->waitting,p));
        if(running->next==NULL)
            running->next=getFirstpcb(ready);
    }
}
void Release()//释放
{
    char name[10];
    struct Node *node;
    struct PCB *temp;
    printf("device name:");
    scanf("%s",name);
    node=FindByName(name,DCTS);
    if(node==NULL || node->process==NULL)
        return;
    else
        {
			temp=node->process;
			if(node->waitting->next==NULL)
			{
				node->process=NULL;
			}
			else
			{
		    node->process=NULL;
			allocate_devices(node,node->waitting);//设备
			getFirstpcb(node->waitting);
			release_controller(node->parent,temp);//释放设备对应的控制器
			}
	}
}

void display_process_status(Nodelist node)//显示节点的占用进程以及等待进程的信息
{
    PCBlist p=node->waitting->next;
    if(node->process!=NULL)//此处是显示占用进程
        {
        printf("<-%s",node->process->name);
        }
    while(p!=NULL)
    {
		printf("\t等待:");
        printf("<--%s",p->name);
        p=p->next;
    }
    printf("\n");
}
void Display_status()
{
	Nodelist chct=CHCTS->next,coct=COCTS->next,dct=DCTS->next;
    while(chct!=NULL)//显示通道
        {
        printf("%s",chct->name);
        display_process_status(chct);
        coct=COCTS->next;
        while(coct!=NULL)//显示控制器
        {
            if(coct->parent==chct)
            {
                printf("\t%s",coct->name);
                display_process_status(coct);
                dct=DCTS->next;
                while(dct!=NULL)//显示设备
                {
                    if(dct->parent==coct)
                    {
                        printf("\t\t%s",dct->name);
                        display_process_status(dct);
                    }
                    dct=dct->next;
                }
            }
            coct=coct->next;
        }
        chct=chct->next;
    }
}


//初始化/菜单选项/主函数
void Init()
{
    int i;
    Nodelist chct,coct;
	running=new PCB;
	ready=new PCB;
	blocked=new PCB;
	ready->next=NULL;
	running->next=NULL;
	blocked->next=NULL;
	create_process("a");
	create_process("b");
	create_process("c");
	create_process("d");
	create_process("e");
	DCTS=new Node;
	DCTS->next=NULL;
	COCTS=new Node;
	COCTS->next=NULL;
	CHCTS=new Node;
    CHCTS->next=NULL;
    chct=Add_Node("CHCT1",NULL,CHCTS);
    coct=Add_Node("COCT1",chct,COCTS);
    Add_Node("K",coct,DCTS);
    Add_Node("M",coct,DCTS);
    chct=Add_Node("CHCT2",NULL,CHCTS);
    coct=Add_Node("COCT2",chct,COCTS);
    Add_Node("P",coct,DCTS);
    chct=Add_Node("CHCT3",NULL,CHCTS);
    coct=Add_Node("COCT3",chct,COCTS);
    Add_Node("D",coct,DCTS);
}
void Menu(){
        printf("----------进程管理----------\n");
        printf("1:创建进程\n");
		printf("2:时间片到\n");
		printf("3:进程阻塞\n");
		printf("4:进程唤醒\n");
		printf("5:进程结束\n");
		printf("6:显示进程状态\n");
		printf("----------设备管理----------\n");
		printf("7:添加\n");//设备或者通道或者控制器
        printf("8:删除\n");
        printf("9:分配设备\n");
        printf("10:释放设备\n");
        printf("11:查看设备状态\n");
		printf("-1:退出\n");
}
int main()
{
	int i;
	Init();
	while(1)
        {
            Menu();
            scanf("%d",&i);
		switch(i)
		{
		default:
			printf("erro");
			continue;
		case 1:
			createNewProcess();
			break;
		case 2:
			timeout();
			break;
		case 3:
			blockCurrentProcess();
			break;
		case 4:
			wakeupBlockedProcess();
			break;
		case 5:
			terminateRunningProcess();
			break;
		case 6:
			display_process();
			break;

        case 7:
			Add_devices();
			break;
        case 8:
			Delete_devices();
			break;
        case 9:
			Allocate();//分配
			break;
        case 10:
			Release();//回收
			break;
        case 11:
			Display_status();
			break;
		
			
			
		}

	}
	return 0;
}

专业方向:软件工程-软件工程(ID:07701) 修订人:金虎 ________________________________________ 《操作系统大作业》教学大纲 第一部分 课程目的与任务 一、课程基础: 在学这门课之前,学生必须预修过高级语言、数据结构、离散数学方面的基本知识,先修操作系统课程,延时完成操作系统大作业。 二、适应对象: 计算机科学与技术-计算机应用; 软件工程-软件工程; 电子信息科学类-电子信息科学与技术;管理类-信息管理专业 、教学目的: 为配合《操作系统》课程的教学,通过模拟操作系统原理的实现,使学生能更深刻地领会操作系统工作原理和操作系统实现方法,并提高程序计能力, 特开此课程计。 四、内容提要: 本课要求模拟采用多道程序计方法的单用户操作系统,该操作系统包括进程管理、存储管理、设备管理和文件管理四部分。 第二部分 内容及基本要求 第1章、进程控制管理实现 ●基本要求:利用简单的结构和控制方法模拟进程结构、进程状态和进程控制。 ●参考学时:8学时 ●参考资料: 用PCB表示整个进程实体,利用随机数方法或键盘控制方法模拟进程执行中产生的事件。或者利用鼠标或者键盘中断的基于图形接口方式的进程控制管理。 1、 定义PCB(可以采用静态结构或动态结构):包括理论PCB中的基本内容,如内部ID、外部ID、进程状态、队列指针。由于无法实现真正的进程创建功能,在实验中只需建立PCB,用它代表完整的进程。 2、 定义进程状态转换方式:进程的状态转换是由进程内部操作或操作系统的控制引起,由于无法实现这些功能,学生可以采用随机数方法或键盘控制方法模拟,并实现对应的控制程序。随机方法指产生1-6的随机数,分别代表创建进程(c)、结束进程(e)、进程阻塞(b)、激活进程(w)、调度进程(p)、时间片到(t)等事件;键盘模拟方法指定义6种按键代表以上6种事件。 3、 根据四种事件处理就绪队列、阻塞队列和当前执行中的进程。 每次事件处理后应形象地显示出当前系统中的执行进程是哪一个,就绪队列和阻塞队列分别包含哪些进程。 第2章、请求分页式存储管理的地址转换过程实现: ●基本要求:实现分页式存储地址转换过程,在此基础上实现请求分页的地址转换。实现请求页式地址转换中出现的缺页现象时,用到的先进先出FIFO、最近最久未使用LRU、最佳OPT置换算法。 ●参考学时:8学时 ●参考资料: 利用键盘输入本模拟系统的物理块的大小,作业的页表中的块号;完成逻辑地址转换成相应的物理地址的过程。 1、建立一张位示图,用来模拟内存的分配情况,利用随机数产生一组0和1的数对应内存的使用情况。 2、输入块(页)的大小,通过模拟位示图为本作业分配内存空间建立相应的页表(长度不定); 3、录入逻辑地址转换成相应的物理地址 4、扩充页表,变成请求式的二维页表(增加存在位等)完成地址转换。 5、输入分配给本作业的块数,模拟作业执行的逻辑地址转换成页面调度次序; 6、分别采用OPT、FIFO、LRU置换算法,利用堆栈结构完成页面置换;记录被换出的页面和新换入的页面。 第3章、设备管理实现: ●基本要求:设备管理主要包括设备的添加和删除、设备分配和回收、同时实现设备独立性。 ●参考学时:6学时 ●参考资料: 假定模拟系统中有键盘、鼠标、打印机和显示器四个设备控制器和两个通道,采用安全分配方式。 1、设备管理子系统涉及到系统设备表(SDT)、通道控制表(CHCT)、控制器控制表(COCT)和设备控制表(DCT)来体现输入输出系统的四级结构和级控制。我们模拟这样的数据结构来完成对外围设备的管理。 (1)添加设备:增加对应的设备控制表和系统设备表中的表项,如果需要新建对应的控制器控制表。 (2)删除设备:删除对应的设备控制表和系统设备表中的表项,如果需要删除对应的控制器控制表。 2、设备分配和回收,进程申请设备的时候,建立起通路,即获成功;否则阻塞到通道控制器设备上面。进程回收设备的时候,把阻塞进程唤醒。 3、设备分配必须满足设备的独立性要求。为了实现设备独立性,要求在驱动程序之上计一层设备无关软件,其主要功能可分为: (1)执行所有设备的公有操作,主要包括:(a)独占设备分配与回收;(b)将逻辑设备名映射为物理设备(LUT),进一步可以找到相应物理设备的驱动程序。 (2)向用户层(或文件层)软件提供统一的接口。例如,对各种设备的读操作,在应用程序中都用read; 而对各种设备的写操作,则都使用write。 第4章、文件管理系统实现: ●基本要求:利用交互式命令实现目录结构和文件管理,同时利用位示图表示外存的分配情况,新建文件时分配必要的空间,模拟文件分配表记录文件在外存上的存储方式。 ●参考学时:8学时 ●参考资料: 在文件中保存目录内容,创建文件或子目录可以用命令行命令:MD、CD、RD、MK(创建文件)、DEL(删除文件)和DIR。目录项包括文件或目录名称、类(文件、目录或空目录项)、创建日期以及下一个目录项指针、下一级目录项指针。 1、创建初始文件,建立根目录的“.”和“..”目录项。 2、显示命令提示符“$”。 3、输入命令后根据命令含义完成相应文件操作: MD:在目录文件中创建子目录,同时搜索当前目录最后一个目录项,并保存指针信息; CD:根据当前目录切换到指定目录; RD:搜索所要删除的目录是否为空目录,若是则删除; MK:在当前目录中创建文件名称;(申请空间利用位示图修改FAT) DEL:搜索所要删除的文件是否存在,若是则删除;(恢复位示图修改FAT) DIR:列出当前目录的所有目录项。 4、在创建文件的时候分配空闲的磁盘空间,采用显示链接的方式,利用文件分配表(FAT)记录文件在外存上的存储情况。 5、当删除文件时,回收外存上的空间,修改位示图和文件分配表。 第5章、进程调度算法的实现: ●基本要求:实现先来先服务FCFS、短作业优先SJF以及时间片轮转调度算法。 ●参考学时:6学时 ●参考资料: 根据创建进程的系统时钟,取相对时钟作为进程的到达时间,利用随机数产生每个进程的估计运行时间。利用模拟系统中提供的算法分别计算其相应的周转时间和带权周转时间。 1、利用绝对时间和相对时钟产生一组进程的到达时刻和运行时间。 2、实现FCFS算法:根据进程的到达时间的先后次序来完成对若干进程的调度。 3、实现SJF算法:根据当前时间已经到达进程的需要运行时间选取其中时间最小的进程最先运行。 4、实现时间片轮转算法:首先要求确定时间片的大小,依据进程的到达时间依次加入队列,每次分配一个时间片大小的时间,如果没有完成参与下一次的竞争,当最后需要一个小于等于时间片的时间时本进程完成,同时退出队列。 5、计算每种算法调度后,系统的平均周转时间和平均带权周转时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值