操作系统大作业

合集下载

“计算机操作系统”课程设计大作业

“计算机操作系统”课程设计大作业

华南理工大学
“计算机操作系统”课程设计大作业
一、题目: 动态内存分区分配方式模拟
二、目的
假设初始态下,可用内存空间为640K,并有下列请求序列,请分别用首次适应算法和最佳适应算法为作业分配和回收内存块,并显示出每次分配和回收后的空闲分区链的情况来以及内存占用情况图。

作业1申请130K
作业2申请60K
作业3申请100k
作业2释放60K
作业4申请200K
作业3释放100K
作业1释放130K
作业5申请140K
作业6申请60K
作业7申请50K
作业6释放60K
三、实验要求:
每人完成一份大作业实验报告。

报告分设计思想、数据定义、处理流程、源程序、运行结果、设计体会等部分。

1)给出数据定义和详细说明;
2)给出实现思想和设计流程;
3)调试完成源程序;
4)屏幕观察运行结果;
5)总结自己的设计体会;
编程工具及操作系统平台不限,建议用VC6. 0或JA V A开发。

四、提交内容
本大作业每个人必须单独完成。

最后需提交的内容包括:源程序(关键代码需要注释说明)、可运行程序、算法思路及流程图、心得体会。

将以上内容刻入光盘,光盘上写明班级、学号、姓名信息,再将大作业要求、源程序及注释、算法思路及流程图、心得体会等打印出来。

最后将打印稿及光盘统一交给教务员。

过期自负。

大作业严禁抄袭。

发现抄袭一律以不及格论。

操作操作系统大型作业

操作操作系统大型作业

操作系统课程设计所在班级:0310401班学生学号:031040109学生姓名:李雨晴论文题目:生产者和消费者问题任课教师:李艳老师完成日期: 2012年12月2日目录操作系统课程设计 (1)一、课程的地位、目标和任务 (3)二、课程设计的基本要求 (3)1.课程设计要求: (3)2.学习要求: (3)三、题目分析 (3)1.题目的特点: (3)2.采用信号量机制: (4)2.1. PV原语操作的动作 (4)2.2信号量 (4)四、课程设计的内容 (5)1.实验程序的结构图(流程图) (5)2. 数据结构及信号量定义的说明 (5)2 .1 CreateThread (5)2.2. CreateMutex (6)2.3. CreateSemaphore (6)2.功能模块 (7)五、课程实现的内容 (7)1.课程设计的实验环境 (7)2. 实验的步骤 (8)2.1 打开VC (8)2.2在工程中创建源文件" R_WP1.cpp": (8)2.3通过调用菜单命令项build->build all进行编译连接 (8)3.代码实现的具体分析 (8)3.1.使用信号量解决生产者-消费者问题 (10)3.2.使用消息传递解决生产者-消费者问题 (12)六、个人体会 (15)参考文献 (15)附录:具体实现代码 (16)一、课程的地位、目标和任务“操作系统”是计算机专业的核心专业课,“操作系统课程设计”是理解和巩固操作系统基本理论、原理和方法的重要实践环节。

本课程通过设计实现一个综合作业,加深对操作系统原理的理解,提高综合运用所学知识的能力,培养学生独立工作和解决问题的能力,取得设计与调试的实践经验,为今后进一步从事计算机系统软件和应用软件的分析、研制和开发打下良好的基础。

二、课程设计的基本要求1.课程设计要求:教学内容:用信号量机制解决生产者和消费者问题。

重点:信号量实现进程同步的算法难点:进程同步的实现2.学习要求:理解生产者和消费者模型,掌握利用信号量实现进程同步的方法,通过对实际问题的编程实现,获得实际应用和编程能力。

操作系统大作业

操作系统大作业

操作系统试验报告姓名:学号:学院:实验一实验要求:获得当前系统中正在运行的所有进程的优先级。

实验程序://实验一:获取当前系统的所有优先级# include <windows.h># include <tlhelp32.h># include <iostream>// 当在用户模式机内核模式下都提供所耗时间时,在内核模式下进行所耗时间的64位计算的帮助方法DWORD GetKernelModePercentage(const FILETIME & ftKernel,const FILETIME & ftUser){// 将FILETIME结构转化为64位整数ULONGLONG qwKernel =( ( (ULONGLONG) ftKernel.dwHighDateTime) << 32) +ftKernel.dwLowDateTime;ULONGLONG qwUser =( ( (ULONGLONG) ftUser.dwHighDateTime) << 32) +ftUser.dwLowDateTime;// 将消耗时间相加,然后计算消耗在内核模式下的时间百分比ULONGLONG qwTotal = qwKernel + qwUser;DWORD dwPct =(DWORD) ( ( (ULONGLONG) 100*qwKernel) / qwTotal) ;return(dwPct) ;}// 以下是将当前运行进程名和消耗在内核模式下的时间百分数都显示出来的应用程序void main(){// 对当前系统中运行的进程拍取"快照"HANDLE hSnapshot = :: CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, // 提取当前进程0) ; // 如果是当前进程,就将其忽略// 初始化进程入口PROCESSENTRY32 pe;:: ZeroMemory(&pe, sizeof(pe) ) ;pe.dwSize = sizeof(pe) ;// 按所有进程循环BOOL bMore = :: Process32First(hSnapshot, &pe) ;while(bMore){// 打开用于读取的进程HANDLE hProcess = :: OpenProcess(PROCESS_QUERY_INFORMATION, // 指明要得到信息FALSE, // 不必继承这一句柄 pe.th32ProcessID) ; // 要打开的进程if (hProcess != NULL){DWORD dwPriority = :: GetPriorityClass(hProcess);// 消除句柄:: CloseHandle(hProcess) ;std::cout<<"Process ID:"<<pe.th32ProcessID<<",Process priority:";switch(dwPriority){case HIGH_PRIORITY_CLASS:std :: cout << "High" ;break;case NORMAL_PRIORITY_CLASS:std :: cout << "Normal" ;break;case IDLE_PRIORITY_CLASS:std :: cout << "Idle" ;break;case REALTIME_PRIORITY_CLASS:std :: cout << "Realtime" ;break;default:std :: cout << "<unknown>" ;break;}std::cout<<std::endl;}// 转向下一个进程bMore = :: Process32Next(hSnapshot, &pe) ;实验二实验要求:进程压力测试(1)用循环的办法产生所要求的进程(线程),循环的退出条件是不能产生进程时,即CreateProcess()返回0时,统计产生的进程(线程)数目;(2)子进程的运行方式分别考虑:子进程挂起或睡眠,挂起操作在父进程通过CREATE_SUSPENDED选项完成;子进程死循环,即父进程产生子进程后子进程立即执行,并且执行一个死循环(3)在进程被赋予不同的优先级情况下的结果实验程序:// proccreate项目# include <windows.h># include <iostream># include <stdio.h>// 创建传递过来的进程的克隆过程并赋于其ID值void StartClone(int nCloneID){// 提取用于当前可执行文件的文件名TCHAR szFilename[MAX_PATH] ;:: GetModuleFileName(NULL, szFilename, MAX_PATH) ;// 格式化用于子进程的命令行并通知其EXE文件名和克隆IDTCHAR szCmdLine[MAX_PATH] ;:: sprintf(szCmdLine, "\"%s\" %d", szFilename, nCloneID) ;// 用于子进程的STARTUPINFO结构STARTUPINFO si;:: ZeroMemory(reinterpret_cast <void*> (&si) , sizeof(si) ) ;si.cb = sizeof(si) ; // 必须是本结构的大小// 返回的用于子进程的进程信息PROCESS_INFORMATION pi;// 利用同样的可执行文件和命令行创建进程,并赋于其子进程的性质BOOL bCreateOK = :: CreateProcess(szFilename, // 产生这个EXE的应用程序的名称szCmdLine, // 告诉其行为像一个子进程的标志NULL, // 缺省的进程安全性NULL, // 缺省的线程安全性FALSE, // 不继承句柄CREATE_NEW_CONSOLE, // 使用新的控制台NULL, // 新的环境NULL, // 当前目录&si, // 启动信息&pi) ; // 返回的进程信息// 对子进程释放引用if (bCreateOK){:: CloseHandle(pi.hProcess) ;:: CloseHandle(pi.hThread) ;}}int main(int argc, char* argv[] ){// 确定进程在列表中的位置int nClone(0) ;if (argc > 1){// 从第二个参数中提取克隆ID:: sscanf(argv[1] , "%d" , &nClone) ;}// 显示进程位置std :: cout << "Process ID: " << :: GetCurrentProcessId() << ", Clone ID: " << nClone<< std :: endl;// 检查是否有创建子进程的需要const int c_nCloneMax = 25;if (nClone < c_nCloneMax){// 发送新进程的命令行和克隆号StartClone(++nClone);}// 在终止之前暂停一下 (l/2秒):: Sleep(10000) ;return 0;}实验三试验要求:使用互斥对象实现线程同步两个线程对同一个变量进行访问,其中一个线程对变量做加1操作,一个线程对其做减1操作。

操作系统大作业

操作系统大作业

操作系统大作业Java语言实现班级:08级计二班姓名:湖南科技大学作业一:生产者与消费者——多线程与同步问题class MyThread {int id;MyThread(int id) {= id;}public String toString() {return"线程" + id;}}class MyStack {tart();new Thread(c).start();}}运行结果截图:作业二:多级反馈队列调度算法;public class Operation {;public class ProcessPCB {;importimportpublic class UserFrame extends JFrame{private static final long serialVersionUID = 1L;JLabel pnamelabel = new JLabel("进程名:");JTextField pnametext = new JTextField();JLabel listlabel1 = new JLabel("正在执行的进程:");JLabel listlabel2 = new JLabel("就绪队列1:");JLabel listlabel3 = new JLabel("就绪队列2:");JLabel listlabel4 = new JLabel("就绪队列3:");JLabel listlabel5 = new JLabel("完成队列:");JTextArea listarea1 = new JTextArea();JTextArea listarea2 = new JTextArea();JTextArea listarea3 = new JTextArea();JTextArea listarea4 = new JTextArea();JTextField executingarea = new JTextField();JButton createbtn = new JButton("创建进程");JButton dispatchbtn = new JButton("开始调度");JButton reset = new JButton("清空");Operation operation = new Operation(); quals("")){(null, "请输入进程标识符和进程名");}else{process = new ProcessPCB( ());(process);}("");ize() > 0){pcb = ().remove(0);ize() > 0){pcb = ().remove(0);ize() > 0){pcb = ().remove(0);;public class Bank {public static void main(String[] args) {int process;//定义进程数量int resource=3;//定义资源种类是3int[] available;//可利用的资源int[][] max,allocation,need;//分别是最大的需求数、已分配的资源、需求资源Scanner scanner=new Scanner;"请输入进程数>>");process=();"请输入可利用资源向量(已定义3个资源种类)>>");available=new int[resource];for (int i = 0; i < resource; i++) {available[i]=();}"请输入分配矩阵");allocation=new int[process][resource];for (int i = 0; i <process ; i++) {"请输入进程"+(i+1)+"已分配的资源数>>");for (int j = 0; j < resource; j++) {allocation[i][j]=();}}"请输入最大需求矩阵");max=new int[process][resource];for (int i = 0; i <process ; i++) {"请输入进程"+(i+1)+"最大需求的资源数>>");for (int j = 0; j < resource; j++) {max[i][j]=();}}need=new int[process][resource];for (int i = 0; i < process; i++) {for (int j = 0; j < resource; j++) {need[i][j]=max[i][j]-allocation[i][j];}}"To时刻的资源分配表");" 进程 max\t\tallocation\t need\t\tavailable");"P0 ");for (int i = 0; i <resource; i++) {" ");}" ");for (int i = 0; i <resource; i++) {" ");}" ");for (int i = 0; i <resource; i++) {" ");}" ");for (int i = 0; i <resource; i++) {" ");}for (int i = 1; i < process; i++) {"P"+i+" ");for (int j = 0; j < resource; j++) {" ");}" ");for (int j = 0; j < resource; j++) {" ");}" ");for (int j = 0; j < resource; j++) {" ");}}int[] work=new int[3];//定义一个数组work用来存放可利用的资源数目for (int i = 0; i < ; i++) {work[i]=available[i];//初始化work}boolean[] finish=new boolean[process];//定义标志finish,表示分配资源的置为true,没有非配的置为falsefor (int i = 0; i < process; i++) {finish[i]=false;//初始化数组finish}int[] array=new int[process];//定义一个数组保存安全序列int num=1;int count1=1;while(num<process){for (int i = 0; i < process; i++) {for (int j = 0; j < 3; j++) {if(finish[i]==false){if(need[i][0]<=work[0]&&need[i][1]<=work[1]&&need[i][2]<=work[2]){for (int j2 = 0; j2 < resource; j2++) {work[j2]=work[j2]+allocation[i][j2];}finish[i]=true;array[count1-1]=i;count1++;}}}}num++;}int count=0;for (int i = 0; i < ; i++) {if(finish[i]==true){count++;}}if(count==process){"存在一个安全序列:");for (int i = 0; i < ; i++) {"P"+array[i]+" ");}}else{"系统处于不安全状态!");}boolean flag=true;while(flag){int[] req=new int[resource];"请输入您要请求资源的编号>>");int choose=();"请输入该进程的请求向量>>");for (int i = 0; i < resource; i++) {req[i]=();}if(req[0]<=need[choose][0]&&req[1]<=need[choose][1]&&req[2]<=need[choose][2]){ if(req[0]<=available[0]&&req[1]<=available[1]&&req[2]<=available[2]){for (int i = 0; i < resource; i++) {available[i]=available[i]-req[i];allocation[choose][i]=allocation[choose][i]+req[i];need[choose][i]=need[choose][i]-req[i];}int[] work1=new int[3];for (int i = 0; i < ; i++) {work1[i]=available[i];}boolean[] finish1=new boolean[process];for (int i = 0; i < process; i++) {finish1[i]=false;}int[] array1=new int[process];int num1=1;int count11=1;while(num1<process){for (int i = 0; i < process; i++) {for (int j = 0; j < 3; j++) {if(finish1[i]==false){if(need[i][0]<=work1[0]&&need[i][1]<=work1[1]&&need[i][2]<=work1[2]){for (int j2 = 0; j2 < resource; j2++) {work1[j2]=work1[j2]+allocation[i][j2];}finish1[i]=true;array1[count11-1]=i;count11++;}}}}num1++;}int count2=0;for (int i = 0; i < ; i++) {if(finish1[i]==true){count2++;}}if(count2==process){"存在一个安全序列:");for (int i = 0; i < ; i++) {"P"+array1[i]+" ");}}else{"系统处于不安全状态!");flag=false;}}else{"资源不够清等待!");}}//if结束else{"请求资源已超过所需资源!");}}//while结束}}运行效果截图:。

操作系统大作业

操作系统大作业

操作系统大作业班级:姓名:学号:实验二:进程压力测试1.实验要求(1)用循环的办法产生所要求的进程(线程),循环的退出条件是不能产生进程时,即CreateProcess()返回0时,统计产生的进程(线程)数目;(2)子进程的运行方式分别考虑:子进程挂起或睡眠,挂起操作在父进程通过CREATE_SUSPENDED选项完成;子进程死循环,即父进程产生子进程后子进程立即执行,并且执行一个死循环(3)在进程被赋予不同的优先级情况下的结果// proccreate项目# include <windows.h># include <iostream># include <stdio.h>// 创建传递过来的进程的克隆过程并赋于其ID值void StartClone(int nCloneID){// 提取用于当前可执行文件的文件名TCHAR szFilename[MAX_PATH] ;:: GetModuleFileName(NULL, szFilename, MAX_PATH) ;// 格式化用于子进程的命令行并通知其EXE文件名和克隆IDTCHAR szCmdLine[MAX_PATH] ;:: sprintf(szCmdLine, "\"%s\" %d", szFilename, nCloneID) ;// 用于子进程的STARTUPINFO结构STARTUPINFO si;:: ZeroMemory(reinterpret_cast <void*> (&si) ,sizeof(si) ) ;si.cb = sizeof(si) ; // 必须是本结构的大小// 返回的用于子进程的进程信息PROCESS_INFORMATION pi;// 利用同样的可执行文件和命令行创建进程,并赋于其子进程的性质BOOL bCreateOK = :: CreateProcess(szFilename, // 产生这个EXE的应用程序的名称szCmdLine, // 告诉其行为像一个子进程的标志NULL, // 缺省的进程安全性NULL, // 缺省的线程安全性FALSE, // 不继承句柄CREATE_NEW_CONSOLE, // 使用新的控制台NULL, // 新的环境NULL, // 当前目录&si, // 启动信息&pi) ; // 返回的进程信息// 对子进程释放引用if (bCreateOK){:: CloseHandle(pi.hProcess) ;:: CloseHandle(pi.hThread) ;}}int main(int argc, char* argv[] ){// 确定进程在列表中的位置int nClone(0) ;if (argc > 1){// 从第二个参数中提取克隆ID:: sscanf(argv[1] , "%d" , &nClone) ;}// 显示进程位置std :: cout << "Process ID: " << :: GetCurrentProcessId()<< ", Clone ID: " << nClone<< std :: endl;// 检查是否有创建子进程的需要const int c_nCloneMax = 25;if (nClone < c_nCloneMax){// 发送新进程的命令行和克隆号StartClone(++nClone);}// 在终止之前暂停一下 (l/2秒):: Sleep(10000) ;return 0;}结果分析:利用同样的可执行文件和命令行创建子进程,并赋于其子进程的性质,CreateProcess()返回0时,能得到进程个数为25个,如图,在进程产生过程中CUP使用率高实验三:使用互斥对象实现线程同步⏹两个线程对同一个变量进行访问,其中一个线程对变量做加1操作,一个线程对其做减1操作。

1《操作系统》大作业题目及要求

1《操作系统》大作业题目及要求

学习中心:
专业:
年级:年春/秋季
学号:
学生:
题目:三进程同步与互斥生产者-消费者问题
1.谈谈你对本课程学习过程中的心得体会与建议?
通过这些实验,让我们对身边的计算机网络有了更为客观、形象、具体的认识。

而不是仅仅限于书本上的文字表达,或者是思维中模糊的想象。

这门实验课程,不仅是对理论课程的巩固,更是对理论课程的扩充。

2.《操作系统》课程设计,从以下5个题目中任选其一作答。

题目三:进程同步与互斥生产者-消费者问题
设计思路:
生产者—消费者问题是一种同步问题的抽象描述。

计算机系统中的每个进程都可以消费或生产某类资源。

当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。

而当某个进程释放资源时,则它就相当一个生产者。

流程(原理)图:
1、生产者
2、消费者。

操作系统大作业(含课程设计)

操作系统大作业(含课程设计)

“计算机操作系统”课程设计大作业一、题目: 页面置换算法模拟实验二、目的分别采用最佳(Optimal)置换算法、先进先出(FIFO)页面置换算法和最近最少使用(LRU)置换算法对用户输入的页面号请求序列进行淘汰和置换,从而加深对页面置换算法的理解。

三、内容和要求请用C/C++语言编一个页面置换算法模拟程序。

用户通过键盘输入分配的物理内存总块数,再输入用户逻辑页面号请求序列,然后分别采用最佳(Optimal)置换算法、先进先出(FIFO)页面置换算法和最近最少使用(LRU)置换算法三种算法对页面请求序列进行转换,最后按照课本P150页图4-26的置换图格式输出每次页面请求后各物理块内存放的虚页号,并算出每种算法的缺页次数。

最后评价三种页面置换算法的优缺点。

三种页面置换算法的思想可参考教材P149-P152页。

假设页面号请求序列为4、3、2、1、4、3、5、4、3、2、1、5,当分配给某进程的物理块数分别为3块和4块时,试用自己编写的模拟程序进行页面转换并输出置换图和缺页次数。

四、提交内容本大作业每个人必须单独完成,大作业以WORD附件形式提交。

最后需提交的内容包括:算法算法思路及流程图、数据结构说明、源程序(关键代码需要注释说明)、运行结果截图、心得体会及总结。

大作业严禁抄袭。

发现抄袭一律以不及格论。

请大家严格按照大作业题目来编写程序,不要上交以前布置的大作业。

如果提交的大作业题目与本文档要求不符,成绩一律为不及格。

请大家按时在网院网上系统里提交大作业,过了规定时间将无法再补交大作业。

答:一、思路页面置换算法:当CPU接收到缺页中断信号,中断处理程序先保存现场,分析中断原因,转入缺页中断处理程序。

该程序通过查找页表,得到该页所在外存的物理块号。

熟悉UNIX/LINUX的常用基本命令,练习并掌握UNIX提供的vi 编辑器来编译C程序,学会利用gcc、gdb编译、调试C程序,学会如何把学到的知识用于解决实际问题,培养学生!。

操作系统大作业

操作系统大作业

操作系统⼤作业操作系统实验报告进程调度实验⼀.实验题⽬⽤C语⾔编写和调试⼀个进程调度程序,模拟进程调度过程。

调度算法采⽤优先数算法和先来先服务算法。

⼆.⽬的要求1.把理论与实践紧密结合,加深对进程的概念及进程调度算法的理解。

取得较好的学习效果2.加深对操作系统课程的理解。

使学⽣更好地掌握操作系统的基本概念、基本原理、及基本功能,具有分析实际操作系统、设计、构造和开发现代操作系统的基本能⼒。

3.培养学⽣的系统程序设计能⼒。

三.实验内容设计⼀个有N个进程并⾏的进程调度程序。

其中:1)进程调度算法:采⽤最⾼优先数优先的调度算法分配处理机和先来先服务算法来排队,总的过程采⽤时间⽚轮转算法。

2)每个进程有⼀个进程控制块(PCB)表⽰。

进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运⾏时间、已⽤CPU时间、进程状态。

3)进程的优先数及需要的运⾏时间可以事先⼈为地指定。

进程的到达时间为进程输⼊的时间。

4)进程的运⾏时间以时间⽚为单位进⾏计算。

5)每个进程的状态可以是就绪W(Wait)、运⾏R(Run)、或完成F(Finish)三种状态之⼀。

6)就绪进程获得CPU后都只能运⾏⼀个时间⽚。

⽤已占⽤CPU时间加1来表⽰。

7)果运⾏⼀个时间⽚后,进程的已占⽤CPU时间已达到所需要的运⾏时间,则撤消该进程;如果运⾏⼀个时间⽚后进程的已占⽤CPU时间还未达所需要的运⾏时间,也就是进程还需要继续运⾏,此时应将进程的优先数减1(即降低⼀级),然后把它插⼊相应优先级就绪队列等待CPU。

8)每进⾏⼀次调度程序都打印⼀次运⾏进程、就绪队列、以及各个进程的PCB,以便进⾏检查。

9)重复以上过程,直到所要进程都完成为⽌。

四.整体功能设计五.进程调度流程图:EXIT六.C语⾔编程实现及数据结构6.1 C程序见报告后⾯的代码6.2 数据结构6.2.1 在实验中共有8个进程。

进程优先级为1到3,进程状态为:“wait”,“run”,“finish”中的⼀种。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

操作系统实验报告进程调度实验一.实验题目用C语言编写和调试一个进程调度程序,模拟进程调度过程。

调度算法采用优先数算法和先来先服务算法。

二.目的要求1.把理论与实践紧密结合,加深对进程的概念及进程调度算法的理解。

取得较好的学习效果2.加深对操作系统课程的理解。

使学生更好地掌握操作系统的基本概念、基本原理、及基本功能,具有分析实际操作系统、设计、构造和开发现代操作系统的基本能力。

3.培养学生的系统程序设计能力。

三.实验内容设计一个有N个进程并行的进程调度程序。

其中:1)进程调度算法:采用最高优先数优先的调度算法分配处理机和先来先服务算法来排队,总的过程采用时间片轮转算法。

2)每个进程有一个进程控制块(PCB)表示。

进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态。

3)进程的优先数及需要的运行时间可以事先人为地指定。

进程的到达时间为进程输入的时间。

4)进程的运行时间以时间片为单位进行计算。

5)每个进程的状态可以是就绪W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。

6)就绪进程获得CPU后都只能运行一个时间片。

用已占用CPU时间加1来表示。

7)果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程;如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入相应优先级就绪队列等待CPU。

8)每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。

9)重复以上过程,直到所要进程都完成为止。

四.整体功能设计五.进程调度流程图:EXIT六.C语言编程实现及数据结构6.1 C程序见报告后面的代码6.2 数据结构6.2.1 在实验中共有8个进程。

进程优先级为1到3,进程状态为:“wait”,“run”,“finish”中的一种。

6.2.2 实验中PCB数据结构:#define finish -1#define wait 0#define run 1typedef struct PCB0{char name[20]; //进程名int priorit; //优先权int reach_time; //到达时间int all_time; //需要运行时间int used_time; //已用时间int state; //进程状态struct PCB0*next;}PCBS;6.3 实验中使用到的进程PCB:PCBS{"a1",3,0,6,0,wait,NULL},{"a2",1,5,5,0,wait,NULL},{"a3",1,12,4,0,wait,NULL},{"a4",3,13,5,0,wait,NULL},{"a5",2,15,5,0,wait,NULL},{"a6",2,18,3,0,wait,NULL},{"a7",3,21,5,0,wait,NULL},{"a8",1,22,4,0,wait,NULL};七.使用说明只需把程序开始的PCBS类型的数组初始化为要将进行调度的作业队列即可。

再运行程序,程序会把运行过程中各PCB的状态输出到桌面上的“pcb.txt”中。

可能有些电脑的桌面位置与程序里设置的位置不同,这时只需改变相关路径就行了。

八.结果分析作业进入内存时按优先级在相应优先级队列中排队,在本程序中有三个优先级,所以设置了三个就绪队列。

给不同优先级的进程在分配处理机时,高优先级队列中的进程优先分配到处理机。

在分配给它的时间片用完后,如果它不是最低优先级,则把它降一级,并插入到相应优先级队列队尾,如果它是最低优先级,则直接把它插入到队尾。

给同一优先级队列中的进程分配处理机时,按先来先服务的方式分配处理机。

从实验过程输出的进程调度信息中,可以明显的看出上述处理机分配原则。

这种分配方式下,高优先级的进程经过几次运行后优先级都会递减到1, 用这种方法能保证每个进程都能分配到处理机,但是,由于优先级递减和先来先服务,使得一些高优先级耗时长的进程不利。

因为最后所有进程都在最低优先级队列里排队,一方面使最低优先级队列过长,另一面使这种调度方式接近基于时间片的先来先服务调度方式。

所以,可以在进程控制块PCB中设置一项,利用该项确定该进程的优先级是否需要递减。

这就可以改进原始调度方式的一些缺点,但这又可能使得低优先级的进程长时间得不到响应,使系统实时性降低。

九.设计体会通过本次实验使我对进程调度的两种方式---先来先服务算法和最高优先数优先的调度算法有了比以前更深入的理解。

通过本次操作系统实验还使我复习了C语言的使用,特别是C中函数和指针的使用。

为了模拟作业从进入内存到运行完毕的过程,程序中使用链表作为数据结构,使用到了两级指针。

我认为操作系统课程是一个实践性很强的课程,为了将理论用于实践必须培养学生的系统程序设计能力,因此,操作系统实验是的一个非常重要的环节。

通过操作系统上机实验,既可以加深对理论的理解,又可以加强将算法用程序设计语言表达的能力。

十.C语言代码运行环境:visual studio 2008// OS2.cpp : 定义控制台应用程序的入口点。

//#include"stdafx.h"#include"stdio.h"#include"string.h"#include"stdlib.h"// For _MAX_PATH definition#include"malloc.h"#define N 8#define finish -1#define wait 0#define run 1//定义进程结构体typedef struct PCB0{char name[20]; //进程名int priorit; //优先权int reach_time; //到达时间int all_time; //需要运行时间int used_time; //已用时间int state; //进程状态struct PCB0 *next;}PCBS;//子函数区域开始//链表创建PCBS *joblistcreate(PCBS *PCB){PCBS *head=NULL,*last=NULL,*p0=NULL;p0= PCB;//开辟节点int i=1;head=p0;last=p0;p0=&PCB[1];while(i<N){last->next=p0;last=p0;//开辟下一个节点if(i<N-1)p0=&PCB[i+1];i++;}return head;}//进程插入void pushpro(PCBS **head,PCBS **head1,PCBS **last1) {PCBS *p=NULL;if(*head1==NULL){*head1=*head;*last1=*head;*head=(*head)->next;(*last1)->next=NULL;}else{p=*head;*head=p->next;(*last1)->next=p;*last1=p;(*last1)->next=NULL;}}//删除进程void pro_over(PCBS **head,PCBS **last){PCBS **p0=NULL;p0=head;(*head)=(*p0)->next;if((*head)==NULL)(*last)=NULL;}//进程循环void proloop(PCBS **head,PCBS **last,PCBS **head1,PCBS **last1){PCBS *p;p=*head;if(*head==*head1){if(*head1==*last1)return;else{*head=(*head)->next;(*last1)->next=p;(*last1)=p;(*last1)->next=NULL;return;}}*head=(*head)->next;if((*head)==NULL)(*last)=NULL;if((*head1)==NULL){*head1=p;*last1=p;}else{(*last1)->next=p;*last1=p;(*last1)->next=NULL;}}//链表打印void listprint(PCBS *head,FILE *fp) {char state[10];PCBS *p0=NULL;p0=head;while(p0!=NULL){switch(p0->state){case -1:strcpy(state,"finish");break;case 0:strcpy(state,"wait");break;case 1:strcpy(state,"run");break;}fprintf(fp,"进程名%s ,优先级%d , 状态%s\n",p0->name,p0->priorit,state);p0=p0->next;}}//打印此刻的运行进程,等待进程void status(PCBS *head3,PCBS *head2,PCBS *head1,int time,FILE *fp) {//打印此刻的运行进程,等待进程fprintf(fp,"############------time = %d------############\n",time-1);listprint(head3,fp);listprint(head2,fp);listprint(head1,fp);//运行进程void running(PCBS **head,PCBS **last,PCBS **head1,PCBS **last1,int time,FILE *fp,PCBS *L3,PCBS *L2,PCBS *L1){PCBS **p0=NULL;p0=head;(*head)->used_time=(*head)->used_time+1;(*head)->state=run;status(L3,L2,L1,time,fp);if((*head)->priorit>1)(*head)->priorit=(*head)->priorit-1;if((*head)->used_time>=(*head)->all_time){(*head)->state=finish;pro_over(head,last);}else{(*head)->state=wait;proloop(head,last,head1,last1);}}//子函数区域完int _tmain(int argc, _TCHAR* argv[]){int time=0; //系统时钟FILE *fp; //文件指针PCBSPCB[]={{"a1",3,0,6,0,wait,NULL},{"a2",1,5,5,0,wait,NULL},{"a3",1,12,4,0,wait, NULL},{"a4",3,13,5,0,wait,NULL},{"a5",2,15,5,0,wait,NULL},{"a6",2,18,3,0,wait,NULL},{"a7",3,21,5,0,wait,NULL},{"a8",1,22,4,0,wait,NULL} }; //系统作业队列puts("\n*********************************\n");printf(" START !\n");//文件写入if((fp=fopen("C:\\Users\\Administrator\\Desktop\\pcb.txt","at+"))==NULL) printf("\nerro!\n");fprintf(fp,"program running imformation!\n");//建立作业队列PCBS*head=NULL,*last=NULL,*head1=NULL,*last1=NULL,*head2=NULL,*last2=N ULL,*head3=NULL,*last3=NULL;PCBS *p0=NULL;//创建作业队列head=joblistcreate(PCB);while(head!=NULL||head1!=NULL||head2!=NULL||head3!=NULL){printf(" time=%d\n",time);//查看有无进程进入,若有则插入相应队列if((head)&&(head->reach_time<=time)){switch(head->priorit){case 3:pushpro(&head,&head3,&last3);break;case 2:pushpro(&head,&head2,&last2);break;case 1:pushpro(&head,&head1,&last1);break;}}time++;//从最高优先级摘下一个进程并执行if(head3!=NULL){running(&head3,&last3,&head2,&last2,time,fp,head3,head2,head1);continue;}else if(head2!=NULL){running(&head2,&last2,&head1,&last1,time,fp,head3,head2,head1);continue;}else if(head1!=NULL){running(&head1,&last1,&head1,&last1,time,fp,head3,head2,head1);continue;}}puts("进程调度信息已写入桌面上文件---pcb.txt 中!");printf(" NORMAL TERMINATION !\n");fclose(fp);return 0;}。

相关文档
最新文档