java实现SP00LING假脱机输入输出技术模拟
来源:互联网 发布:java可变长参数 使用 编辑:程序博客网 时间:2024/06/06 07:40
Basic Framework
- 进程调度算法
进程调度采用随机算法,这与进程输出信息的随机性相一致。两个请求输出的用户进程的调度概率各为45%,SP00LING输出进程为10%,这由随机数发生器产生的随机数来模拟决定。
进程状态
进程有5种状态:0为可执行态;
1为等待状态1,表示输出井满,请求输出的用户进程等待;
2为等待状态2,表示请求输出井空,SP00LING输出进程等待;
3为等待状态3,表示请求输出井满,请求输出的用户进程等待;
4为结束态,进程执行完成。进程基本状态有3种,分别为可执行、等待和结束。可执行态就是进程正在运行或等待调度的状态;等待状态又分为等待状态1、等待状态2和等待状态3。
状态变化的条件为:
①进程执行完成时,置为“结束”态。
②服务程序在将输出信息送输出井时,如发现输出井已满,将调用进程置为“等待状态1”。
③SP00LING进程在进行输出时,若输出井空,则进入“等待状态2”。
④SP00LING进程输出一个信息块后,应立即释放该信息块所占的输出井空间,并将正在等待输出的进程置为“可执行状态”。
⑤服务程序在输出信息到输出井并形成输出请求信息块后,若SP00LING进程处于等待态,则将其置为“可执行状态”。
⑥当用户进程申请请求输出块时,若没有可用请求块时,调用进程进人“等待状态3”。
PCB.java
package Spooling;public class PCB { int ID;//进程标识数 int status;//进程状态 int outputFileCount;//要输出的文件数 int outPut_X;//进程输出时的临时变量}
requireBlock.java
package Spooling;public class requireBlock { int requireName; //请求进程名 int length;//本次输出信息长度 int outputHeadAddress;//信息在输出井的首地址}
Manage.java
package Spooling;import java.util.Random;import javax.swing.JTextArea;import javax.swing.JTextField;public class Manage extends Thread{ PCB pcb[]; requireBlock requireblock[]; int buffer[][]; int outputBufferSpace[];//可使用的输出井buffer空间 int outputBufferPointer[][]; //输出井buffer空闲和满指针 int requireblockNumber; //requireblock的剩余数量 int requireblockOutputPointer; //要输出的第一个reqblock指针 int requireblockFreePointer; //第一个空闲reqblock指针 double random; //用于调度三个进程的控制随机数 int output1; //用户进程1已生成的文件数 int output2; //用户进程2已生成的文件数 int output_1; //用户进程1已输出的文件数 int output_2; //用户进程2已输出的文件数 int x; //随机生成的数据0~9 int i; //临时控制变量 Random x1; //辅助生成随机数据x:0~9 Spooling spooling; public Manage( Spooling spooling ){//对各进程的数据初始化 output1 = 0; output2 = 0; output_1 = 0; output_2 = 0; pcb = new PCB[4]; requireblock = new requireBlock[10]; buffer = new int[3][100]; outputBufferSpace = new int[3]; outputBufferSpace[1] = 100; outputBufferSpace[2] = 100; outputBufferPointer = new int[3][4]; outputBufferPointer[1][0] = 0; outputBufferPointer[2][0] = 0; requireblockNumber = 10; requireblockOutputPointer = 0; requireblockFreePointer = 0; x1 = new Random(); for( i = 0; i < 4; i++ ){ pcb[ i ] = new PCB(); } for( i = 0; i < 10; i++ ){ requireblock[ i ] = new requireBlock(); } for( i = 1; i <=3; i++ ){ pcb[ i ].status = 0; } this.spooling = spooling;//对各进程的数据初始化完毕 把这个传过来有助于更新界面内容 } public void run(){ //进程调度 do{ //while循环 random = Math.random();//产生一个随机数,控制进程调度,令用户进程概率为45%,Spooling进程为10% if( random <= 0.45 && pcb[ 1 ].status == 0 ){ //调度用户进程1 spooling.textArea4.append( "调度用户进程1\n" ); try{ sleep( 500 ); } catch( InterruptedException e ){ e.printStackTrace(); } ///调用用户函数去生成文件填入输出井生成请求块 output1 = user( 1, output1, spooling.textArea1, spooling.field1 ); } else if( random >0.45 && random <= 0.9 && pcb[ 2 ].status == 0 ){ //调度用户进程2 spooling.textArea4.append( "调度用户进程2\n" ); try{ sleep( 500 ); } catch( InterruptedException e ){ e.printStackTrace(); } output2 = user( 2, output2, spooling.textArea2, spooling.field2 ); } else if( random >0.9 && random <= 1 && pcb[3].status == 0 ){ //调度spooling进程 spooling.textArea4.append("调度Spooling进程\n"); try{ sleep( 500 ); } catch( InterruptedException e ){ e.printStackTrace(); } spooling1(); } } while( pcb[1].status != 4 || pcb[2].status != 4 || pcb[3].status != 4 ); // 当都是结束状态曾程序运行完成 spooling.textArea4.append("程序运行完毕\n"); //进程调度结束 } public int user( int name, int out, JTextArea textarea, JTextField field ){ //用户进程 返回已经生成的文件数目 pcb[ name ].ID = name; pcb[ name ].outputFileCount = Integer.parseInt( field.getText() ); while( out != pcb[ name ].outputFileCount ){//判断进程所要输出的文件是否输出完毕的while循环 outputBufferPointer[ name ][ 1 ] = outputBufferPointer[ name ][ 0 ]; do{ //判断进程的一个文件是否输出完毕的while循环 x = x1.nextInt( 9 );//x为每次随机生成的数据0~9,送入pcb.x pcb[ name ].outPut_X = x; if( outputBufferSpace[ name ] == 0 ){ //若输出井buffer满,变为等待状态1,转调度程序 pcb[ name ].status = 1; //一个文件的长度是未知的在创建的过程中如果发现井满了要退回去 if( outputBufferPointer[ name ][ 0 ] >= outputBufferPointer[ name ][5] ){ outputBufferSpace[ name ] = outputBufferSpace[ name ] + outputBufferPointer[ name ][ 0] - outputBufferPointer[ name ][ 1 ];//将空间释放 } else{ outputBufferSpace[ name ] = outputBufferSpace[ name ] + 100 + outputBufferPointer[ name ][ 0] + outputBufferPointer[ name ][ 1 ]; } outputBufferPointer[ name ][ 0 ] = outputBufferPointer[ name ][ 1 ]; //将空间释放 textarea.append( "第" + ( out + 1 ) + "个文件缺少输出井" ); textarea.append( "进入等待状态1\n" ); try{ sleep( 500 ); } catch( InterruptedException e ){ e.printStackTrace(); } return out; } else{//若输出井没满 buffer[ name ][ outputBufferPointer[ name ][ 0 ] ] = pcb[ name ].outPut_X; //进程的输出信息PCB[i].x送buffer[i][ outputBufferPointer[i][0]] outputBufferSpace[ name ] = outputBufferSpace[ name ] - 1; //输出井空闲个数减1 outputBufferPointer[ name ][ 0 ] = ( outputBufferPointer[ name ][ 0 ] + 1 ) % 100; //修改空缓冲区指针outputBufferPointer[i][0]前进1 } } while( x != 0 ); //判断进程的一个文件是否输出完毕的while循环结束 if( outputBufferPointer[ name ][ 0 ] == 0 ){ textarea.append( (out + 1) + " " + outputBufferPointer[ name ][ 1 ] + " ~ " + " 99 " + outputBufferSpace[ name ] + " "); } else{ textarea.append( (out + 1) + " " + outputBufferPointer[ name ][ 1 ] + " ~ " + ( outputBufferPointer[ name ][ 0 ] - 1 ) + " " + outputBufferSpace[ name ] + " " ); } try{ sleep( 500 ); } catch( InterruptedException e ){ e.printStackTrace(); } out++; //成功生成了一个文件 //接下来要生成相应的请求块 if( requireblockNumber == 0 ){//若没有空闲请求输出块,转为等待状态3 pcb[ name ].status = 3; textarea.append( "缺少请求输出块" ); textarea.append( "进入等待状态3 \n" ); try{ sleep( 500 ); } catch( InterruptedException e ){ e.printStackTrace(); } return out; } else{ //若有空闲请求输出块 requireblock[ requireblockFreePointer ].outputHeadAddress = outputBufferPointer[ name ][ 1 ]; //将文件在输出井的位置填入空闲请求块 if( outputBufferPointer[ name ][ 0 ] >= outputBufferPointer[ name ][ 1 ] ){ //将文件在输出井的长度填入空闲请求块 requireblock[ requireblockFreePointer ].length = outputBufferPointer[ name ][ 0 ] - outputBufferPointer[ name ][ 1 ]; } else{ requireblock[ requireblockFreePointer ].length = 100 - outputBufferPointer[ name ][ 1 ] + outputBufferPointer[ name ][ 0 ]; } requireblock[ requireblockFreePointer ].requireName = name; //将进程名i填入请求块 textarea.append( "获得请求输出块" + Integer.toString( requireblockFreePointer +1 ) + "\n"); requireblockFreePointer = ( requireblockFreePointer + 1 ) % 10;//修改空闲请求块指针 requireblockNumber--; if( pcb[ 3 ].status == 2 ){ //若SPOOLING进程是等待状态,则唤醒SPOOLING进程 pcb[ 3 ].status = 0; } } }//判断进程所要输出的文件是否输出完毕的while循环结束 textarea.append( "进程" + name + "输出完毕!" );//文件输出完毕,修改状态为结束,转进程调度 pcb[ name ].status = 4; return out; } public void spooling1(){ while( requireblockNumber != 10 ){ //判断请求输出块是否为空的while循环 //若请求输出块不为空 StringBuffer stringBuffer = new StringBuffer( 100 ); for ( i = 0; i<requireblock[ requireblockOutputPointer ].length; i++) {//按该请求输出信息块requireblock[]的指针requireblockOutputPointer将输出井中的一个文件的内容放入临时buffer1中 stringBuffer.append( buffer[ requireblock[ requireblockOutputPointer ].requireName ][ requireblock[ requireblockOutputPointer ].outputHeadAddress] ); requireblock[ requireblockOutputPointer ].outputHeadAddress = ( requireblock[ requireblockOutputPointer ].outputHeadAddress + 1 )%100; } if( requireblock[ requireblockOutputPointer ].requireName == 1){ output_1++; spooling.textArea3.append( "User1第" + output_1 + "个文件:"); } else{ output_2++; spooling.textArea3.append( "User2第" + output_2 + "个文件:"); } spooling.textArea3.append( stringBuffer.toString() + "\n" ); try{ sleep( 500 ); } catch( InterruptedException e ){ e.printStackTrace(); } //释放相应输出井,即修改相应的输出井计数outputBufferSpace outputBufferSpace[ requireblock[ requireblockOutputPointer ].requireName ] = outputBufferSpace[ requireblock[ requireblockOutputPointer ].requireName ] + requireblock[ requireblockOutputPointer ].length; requireblockOutputPointer = ( requireblockOutputPointer + 1 )%10; requireblockNumber++; for( int k = 1; k <= 2; k++ ){ if( pcb[ k ].status == 3 ){ //有等待请求输出块的进程,唤醒没有请求块的进程 一次输出进程完成只能解禁一个请求块所以要完成一个就切断 //应该看先是否有等待请求块的进程,这样可以尽早释放相应的井空间 pcb[ k ].status = 0; requireblock[ requireblockFreePointer ].outputHeadAddress = outputBufferPointer[ k ][ 1 ];//将文件在输出井的位置填入空闲请求块 if( outputBufferPointer[ k ][ 0 ] >= outputBufferPointer[ k ][ 1 ] ){ //将文件在输出井的长度填入空闲请求块 requireblock[ requireblockFreePointer ].length = outputBufferPointer[ k ][ 1 ]; } else{ requireblock[ requireblockFreePointer ].length = 100 - outputBufferPointer[ k ][ 1] + outputBufferPointer[ k ][ 0 ]; } requireblock[ requireblockFreePointer ].requireName = k;//将进程名i填入请求块 if( k ==1 ){ spooling.textArea1.append("第" + output1 + "个文件获得请求输出块" + ( Integer.toString( requireblockFreePointer + 1 ) ) + "\n" ); } if( k == 2 ){ spooling.textArea2.append("第" + output2 + "个文件获得请求输出块" + ( Integer.toString( requireblockFreePointer + 1 ) ) + "\n" ); } requireblockFreePointer = ( requireblockFreePointer +1 )%10;//修改空闲请求块指针 requireblockNumber--; //空闲请求块数减1 if( pcb[ 3 ].status == 2 ){ //若SPOOLING进程是等待状态,则唤醒SPOOLING进程 pcb[ 3 ].status = 0; } return; //完成一个就切断, 可能两个都等待请求块,但先满足一个吧 } } for( int k =1; k <=2; k++ ){ if( pcb[ k ].status ==1 ){ //有等待输出井的进程,唤醒相应进程 pcb[ k ].status = 0; return; } } }//判断请求输出块是否为空的while循环结束 if( pcb[ 1 ].status ==4 && pcb[ 2 ].status ==4 ){//进程1、2结束后输出进程结束 pcb[ 3 ].status = 4; spooling.textArea3.append( " Spooling输出进程结束" ); return; } else{ spooling.textArea3.append( "调度spooling输出程序,请求块空,输出进程转入状态2\n" ); pcb[ 3 ].status = 2; } }}
Spooling.java
package Spooling;import java.awt.BorderLayout;import java.awt.Container;import java.awt.FlowLayout;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;import javax.swing.SwingConstants;public class Spooling extends JFrame implements ActionListener{ JPanel panel1; JPanel panel2; JPanel panel3; JTextField field1; JTextField field2; JScrollPane p1; JScrollPane p2; JScrollPane p3; JScrollPane p4; JTextArea textArea1; JTextArea textArea2; JTextArea textArea3; JTextArea textArea4; JButton button; Manage manage; public Spooling(){ //界面构造函数 manage = new Manage( this ); Container container = this.getContentPane(); container.setLayout( new BorderLayout() ); field1 = new JTextField( 3 );//设置panel1 field2 = new JTextField( 3 ); button = new JButton( "运行" ); button.addActionListener( this ); panel1 = new JPanel(); panel1.setLayout( new FlowLayout() ); panel1.add( new JLabel( "用户进程1文件数:", SwingConstants.RIGHT ) ); panel1.add( field1 ); panel1.add( new JLabel( "用户进程2文件数:", SwingConstants.RIGHT) ); panel1.add( field2 ); panel1.add( button ); //设置panel1完毕 textArea1 = new JTextArea( 80,100 );//设置panel2 textArea2 = new JTextArea( 112,400 ); textArea1.append( "用户进程1的文件生成情况及状态变换\n文件序号 位 置 剩余空间 状态\n" ); textArea2.append("用户进程2的文件生成情况及状态变换\n文件序号 位 置 剩余空间 状态\n"); p1 = new JScrollPane( textArea1 ); p2 = new JScrollPane( textArea2 ); panel2 = new JPanel(); panel2.setLayout ( new GridLayout( 1,2 ) ); panel2.add( p1 ); panel2.add( p2 ); //设置panel2完毕 textArea3 = new JTextArea( 15,400 );//设置panel3 textArea4 = new JTextArea( 15,150 ); textArea3.append( "打印输出\n" ); textArea4.append("主程序调度\n"); p3 = new JScrollPane( textArea3 ); p4 = new JScrollPane( textArea4 ); panel3 = new JPanel(); panel3.setLayout( new GridLayout( 1,2 ) ); panel3.add( p3 ); panel3.add( p4 ); container.add( panel1, BorderLayout.NORTH );//设置窗口 container.add( panel2 ,BorderLayout.CENTER ); container.add( panel3, BorderLayout.SOUTH ); this.setSize( 1200,600 ); this.setLocation( 100,100 ); this.setTitle( "Spooling" ); this.setVisible( true ); this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );//设置窗口完毕 } public void actionPerformed( ActionEvent e ){ manage.start(); } public static void main( String args[] ){ Spooling spooling = new Spooling(); }}
Running Effect
Source Download
Please click the address->spooling
Summarize
原文地址:www.iooy.com
阅读全文
1 0
- java实现SP00LING假脱机输入输出技术模拟
- 假脱机技术
- SPOOLING假脱机技术
- 联机、脱机、假脱机
- Python模拟java输入输出流
- 假脱机
- java实现输入输出图片
- 技术开篇-java输入输出流
- 模拟带Servlet技术的HTTP服务器的Java实现
- java命令行中实现输入输出
- 脱机外挂制作完全版(制作原理与实现技术)
- 脱机外挂制作完全版(制作原理与实现技术)
- 脱机外挂制作完全版(制作原理与实现技术)
- 输入输出技术
- 【操作系统】SPOOLing技术(外部设备联机并行操作/假脱机技术)
- 清除假脱机请求
- eclipse通过控制台实现java的输入输出
- java模拟GBN实现
- JDBC
- 手把手教你用Hexo+(Coding/GitHub)搭建个人博客及绑定私有域名
- java IO流学习总结
- Javascript中事件对象event和e
- android 6.0版本适配的几个重要方面
- java实现SP00LING假脱机输入输出技术模拟
- 数据透视表 笔记
- 哈尔滨理工大学第七届程序设计竞赛决赛(网络赛-高年级组)D 数圈圈【DFS||数位DP】
- Android踩坑日记:android7.0动态相机权限
- 《Java并发编程的艺术》第四章——Java并发编程基础
- ZooKeeper 原理及其在 Hadoop 和 HBase 中的应用
- 递归思想和实例
- linux wget 命令用法详解(附实例说明)
- 浅谈Java中的hashcode方法