操作系统实验之设备管理

目录

一、实验目的

二、实验内容

三、实验思路

四、主要数据结构

五、实现代码

六、实验结果



一、实验目的

通过这次实验,理解设备管理的概念和任务。实现设备管理功能的模拟,主要包括通道和控制器的添加和删除,设备的添加、删除,设备的分配和回收。

二、实验内容

1、假定模拟系统中已有键盘、鼠标、打印机和显示器四个设备,另有三个控制器和两个通道。

3、实现上述设备、控制器以及通道的层次关系,同时能够添加或删除新的设备、控制器或通道。

4、通过键盘命令模拟进程执行过程中提出的设备分配或释放请求,并为此请求分配或释放设备。分配设备成功后可将进程状态调整为阻塞,释放设备后变为就绪状态。

5、分配设备时应如果该设备已被其它进程占用,则设备分配失败,请求进程进入阻塞状态,同时等待该设备的释放。如果设备空闲,进程占用设备的同时还应提出申请控制器请求,直到与设备相关的通道都已申请成功为止。

三、实验思路

通道、控制器、设备的关系:一个通道可以控制多个设备控制器,每个设备控制器可以控制多个设备,属于树型结构关系。

当某进程申请设备时,当且仅当该进程需要的控制器、通道、设备均空闲,才能申请成功,否则需要进入相应的阻塞队列。等待某进程的释放,才能唤醒三个阻塞队列的队首。

本实验为系统初始化若干个设备、控制器、通道,使进程分别申请、释放设备,模拟操作系统的设备管理操作。同时实现设备、控制器、通道的增加和删除。

四、主要数据结构

PCB:记录进程名、申请设备名。

设备、控制器、通道节点:记录名称、占用该节点的进程、等待该节点的进程队列、前驱节点。

链表:设备、控制器、通道表。

等待队列:设备等待队列、控制器等待队列、通道等待队列,由等待节点的进程构成,当进程释放某个节点后,自动唤醒等待队列队首进程。

树型结构:通道、控制器、设备的关系:一个通道可以控制多个设备控制器,每个设备控制器可以控制多个设备。

五、实现代码

//pcb
public class pcb {
	String name;//进程名
	String device;//申请设备名
	public pcb(String name, String device) {
		super();
		this.name = name;
		this.device = device;
	}
	@Override
	public String toString() {
		return "" + name + "";
	}
}
import java.util.Queue;

//通道、控制器、设备的关系:一个通道可以控制多个设备控制器,每个设备控制器可以控制多个设备 树型结构
//通道、控制器、设备节点:
public class Node {
	String name; // 名称
	pcb process; // 占用该节点的进程
	Queue waitinglist; // 等待该节点的进程队列:由进程PCB组成
	Node parent; // 父节点

	public Node(String name, pcb process, Queue waitinglist, Node parent) {
		super();
		this.name = name;
		this.process = process;
		this.waitinglist = waitinglist;
		this.parent = parent;
	}
}
import java.util.LinkedList;
//设备基本信息节点:
public class sNode {
	String name;//设备名称
	String type;//设备类型
	LinkedList dct;//dct设备控制表
	int state;
	public sNode(String name, String type,int state, LinkedList dct) {
		super();
		this.state = state;
		this.name = name;
		this.type = type;
		this.dct = dct;
	}
}
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class IO_management {
    public static LinkedList CHCT;//通道控制表
    public static LinkedList COCT;//控制器控制表
    public static LinkedList DCT;//设备控制表:记录设备使用情况
    public static LinkedList SDT;//系统设备表:记录系统中全部设备的情况
    public static Queue channel_w,controller_w,device_w; //通道等待队列 控制器等待队列 设备等待队列
    public static void main(String[] args) {
		// TODO Auto-generated method stub
		init();
//		showSDT();
		while(true) {
        Scanner scan=new Scanner(System.in);
        System.out.println("**********************************************************************************");
        showSDT();
        System.out.println("------------------设备管理系统------------------");
        System.out.println("1.设备分配  2.设备回收  3.添加设备  4.删除设备");
        System.out.println("5.添加控制器 6.删除控制器 7.添加通道 8.删除通道 9.退出");
        System.out.println("请输入功能编号:");
        int choice=Integer.parseInt(scan.nextLine());
        switch (choice) {
		case 1:
//			showSDT();
			System.out.print("请输入进程名:");
			String pname=scan.nextLine();
			System.out.print("请输入设备类型:");
			String dname=scan.nextLine();
			allocation(new pcb(pname, dname));
			break;
        case 2:
        	System.out.print("请输入进程名:");
			String pname2=scan.nextLine();
			System.out.print("请输入设备类型:");
			String dname2=scan.nextLine();
			recovery(new pcb(pname2, dname2));
        	break;
        case 3:
        	addDevice();
//        	show();
        	break;
        case 4:
			delDevice();
//			show();
			break;
        case 5:
        	addController();
//        	show();
        	break;
        case 6:
        	delController();
//        	show();
        	break;
        case 7:
			addChannel();
//			show();
			break;
        case 8:
        	delChanner();
//        	show();
        	break;
        case 9:
        	System.out.println("-------------------退出程序-------------------");
        	return;
		default:
			System.out.println("序号有误!");
			break;
		}
		}
	}
	//初始化
	public static void init() {
		//通道控制表
		CHCT=new LinkedList<>();
	    Node c1=new Node("channel1",null,channel_w,null);
	    Node c2=new Node("channel2",null,channel_w,null);
	    CHCT.add(c1);
	    CHCT.add(c2);
		//控制器控制表
		COCT=new LinkedList<>();
		Node co1=new Node("controller1", null, controller_w, c1);
		Node co2=new Node("controller2", null, controller_w, c1);
		Node co3=new Node("controller3", null, controller_w, c2);
		COCT.add(co1);
		COCT.add(co2);
		COCT.add(co3);
		//设备控制表
		DCT=new LinkedList<>();
		Node d1=new Node("鼠标", null, device_w, co1);
		Node d2=new Node("键盘", null, device_w, co1);
		Node d3=new Node("打印机", null, device_w, co2);
		Node d4=new Node("显示器", null, device_w, co3);
		DCT.add(d1);
		DCT.add(d2);
		DCT.add(d3);
		DCT.add(d4);
		//系统设备表
		SDT=new LinkedList<>();
		sNode s1=new sNode("鼠标1", "鼠标",0, DCT);
		sNode s2=new sNode("键盘1", "键盘", 0,DCT);
		sNode s3=new sNode("打印机1", "打印机",0, DCT);
		sNode s4=new sNode("显示器1", "显示器", 0,DCT);
		SDT.add(s1);
		SDT.add(s2);
		SDT.add(s3);
		SDT.add(s4);
		//等待队列
		channel_w=new LinkedList<>();
		controller_w=new LinkedList<>();
		device_w=new LinkedList<>();
	}
	//设备分配:DCT->COCT->CHCT
	//独占设备:如果该设备已被其它进程占用,则设备分配失败,请求进程进入阻塞状态,同时等待该设备的释放。如果设备空闲,进程占用设备的同时还应提出申请控制器请求,直到与设备相关的通道都已申请成功为止。
	public static void allocation(pcb p) {
		Node d=null;
		sNode f = null;
		int num = 0;
		//查看设备控制表
		
		for (int i = 0; i < SDT.size(); i++) {
			if(p.device.equals(SDT.get(i).type)) {
				num++;
				if(SDT.get(i).state == 0) {
				f = SDT.get(i);
				break;
				}
			}
		}
		for (int i = 0; i < DCT.size(); i++) {
			if (p.device.equals(DCT.get(i).name)) {
				num--;
				if(num == 0) {
				d=DCT.get(i);
				break;
				}
			}
		}
		
		if(f == null) {
			System.out.println("无设备可用!申请失败");
			device_w.offer(p);
			return;
		}
		//该设备已被其他进程占用
		if (d.process!=null) {
			//进入阻塞队列
			System.out.println("设备被占用!申请失败");
			device_w.offer(p);
			return;
		}
		else {
			//查看其控制器是否空闲
			//该控制器被占用
			if (d.parent.process!=null) {
				//进入阻塞队列
				System.out.println("设备控制器被占用!"+p.name+"申请"+p.device+"失败");
				controller_w.offer(p);
				return;
			}
			else {
				//查看其通道是否空闲
				//该通道被占用
				if (d.parent.parent.process!=null) {
					//进入阻塞队列
					System.out.println("通道被占用!"+p.name+"申请"+p.device+"失败");
					channel_w.offer(p);
					return;
				}
				else {
					//修改各个节点的process信息
					f.state = 1;
					d.process=p;
					d.parent.process=p;
					d.parent.parent.process=p;
					System.out.println("进程"+p.name+"申请"+p.device+"设备成功");
				}
			}
		}
	}
    //设备回收:释放进程占用的设备、控制器、通道资源。并唤醒其阻塞队列的一个进程
	public static void recovery(pcb p) {
		Node d=null;
		//查看设备控制表
		for (int i = 0; i < DCT.size(); i++) {
			if (p.device.equals(DCT.get(i).name)) {
				d=DCT.get(i);
				break;
			}
		}
		for (int i = 0; i < SDT.size(); i++) {
			if(p.device.equals(SDT.get(i).type)&&SDT.get(i).state==1){
				SDT.get(i).state = 0;
			}
		}
		System.out.println(p.device+"回收成功!");
		//释放设备:修改其process为null
		d.parent.parent.process=null;
		pcb n1=channel_w.poll();
		d.parent.process=null;
		pcb n2=controller_w.poll();
		d.process=null;
		pcb n3=device_w.poll();
		//唤醒不为空的阻塞队列的队首进程
		if (n1!=null) {
			allocation(n1);
		}
		if (n2!=null) {
			allocation(n2);
		}
		if (n3!=null) {
			allocation(n3);
		}
		
	}
	//添加设备
	public static void addDevice() {
		Scanner scan=new Scanner(System.in);
		System.out.print("请输入设备名称:");
		String name=scan.nextLine();
		System.out.print("请输入设备类型:");
		String type=scan.nextLine();
		//将设备添加入SDT
		SDT.add(new sNode(name, type,0, DCT));
		System.out.print("请输入控制器名称:");
		String ne=scan.nextLine();
		//查询COCT表
		for (int i = 0; i < COCT.size(); i++) {
			if (COCT.get(i).name.equals(ne)) {
				//将设备添加入DCT
				DCT.add(new Node(type, null, device_w, COCT.get(i)));
				break;
			}
		}
		System.out.println(name+"添加成功!");
//		show();
	}
	//删除设备
	public static void delDevice() {
		Scanner scan=new Scanner(System.in);
		System.out.print("请输入设备名称:");
		String name=scan.nextLine();
		//从SDT表中删除
		for (int i = 0; i < SDT.size(); i++) {
			if (SDT.get(i).type.equals(name)) {
				SDT.remove(SDT.get(i));
				break;
			}
		}
		//从DCT表中删除
		for (int i = 0; i < DCT.size(); i++) {
			if (DCT.get(i).name.equals(name)) {
				DCT.remove(DCT.get(i));
				break;
			}
		}
		System.out.println(name+"删除成功!");
//		show();
	}
	//添加控制器
	public static void addController() {
		Scanner scan=new Scanner(System.in);
		System.out.print("请输入控制器名称:");
		String name=scan.nextLine();
		System.out.print("请输入通道名称:");
		String ne=scan.nextLine();
		//将控制器添加入COCT表
		//查询CHCT表
		for(int i=0;i"+p.parent.name);
			}
		}
	}
	public static void show2() {
		System.out.println("******************************************");
		System.out.println("通道");
		for (int i = 0; i < CHCT.size(); i++) {
			System.out.println(CHCT.get(i).name);
		}
		
	}
}
	

六、实验结果

你可能感兴趣的:(操作系统,java)