操作系统实验指导书2013(梁宝华)

合集下载

操作系统实验指导书-final

操作系统实验指导书-final

中央民族大学操作系统实验指导书目录前言 (3)实验总体要求 (4)实验格式 (5)实验一:Linux的初步认识 (6)实验二: 系统调用实验 (9)实验三:进程同步实验 (16)实验四:进程通信实验 (21)实验五:页面调度算法模拟 (28)实验六:虚拟文件系统 (31)实验七:Linux Socket编程 (79)附加实验:linux的深入认识 (86)前言《操作系统》课程是计算机科学与技术专业的主干课。

操作系统是现代计算机系统中必不可少的基本系统软件,对计算机系统资源实施管理,是所有其他软件与计算机硬件的唯一接口,所有用户在使用计算机时都要得到操作系统提供的服务。

《操作系统》课程是一门理论和实践相结合的课程。

通过《操作系统》实验教学,可以是使学生深入地掌握操作系统的基本概念、基本原理,同时也可以使学生能够运用《操作系统》提供的方法与技巧对实际问题进行算法设计和程序设计,即能更好地实现与课程同步练习,又进一步深化理解和灵活掌握教学内容;又能培养学生程序设计及上机调试的能力。

这将为其后继课程如《计算机体系结构》、《计算机网络》等打下必要的基础,同时也为今后在相关领域开展工作打下坚实的基础。

《操作系统》课程含有18学时的实验内容,要求学生完成linux的初步认识、进程同步、进程通信、页面调度算法模拟等实验,使学生了解和掌握操作系统的基本原理,掌握常用操作系统的使用和一般的管理方法等内容。

通过《操作系统》实践环节,培养学生认真分析问题、解决问题的能力,同时培养学生面对问题勤于思考及团队合作的意识,最终使学生达到理论与实践相结合的目的。

《操作系统》实验教学计划安排7个实验项目。

由于每个项目都是一个综合训练,仅仅依靠上机三个学时是远远不够的,尤其是实验6和实验7,具有很大的难度,教师可以根据学生的实际情况调整实验内容。

这里要求每个同学上实验课前必须做好充分的准备,如问题的分析、数据类型和系统的设计以及程序的编写、初步的调试等等,上机实验课主要是教师和同学们一起讨论和交流,共同解决系统设计和调试中的问题。

操作系统实验指导书

操作系统实验指导书

操作系统实验指导目录实验一 Windows2000进程观测 (1)实验二 Windows2000进程控制 (6)实验三Windows2000线程的运行 (14)实验四Windows2000线程同步 (19)实验五经典同步问题的实现 (27)实验六Windows2000内存管理 (31)实验七Windows2000文件管理 (40)实验八安装Linux操作系统 (48)实验九Linux 基本操作 (49)实验十Linux下的进程与线程 (55)实验一 Windows2000进程观测一、背景知识Windows 2000可以识别的应用程序包括控制台应用程序、GUI应用程序和服务应用程序。

控制台应用程序可以创建GUI,GUI应用程序可以作为服务来运行,服务也可以向标准的输出流写入数据。

不同类型应用程序间的惟一重要区别是其启动方法。

Windows 2000是以NT的技术构建的,它提供了创建控制台应用程序的能力,使用户可以利用标准的C++工具,如iostream库中的cout和cin对象,来创建小型应用程序。

当系统运行时,Windows 2000的服务通常要向系统用户提供所需功能。

服务应用程序类型需要ServiceMail() 函数,由服务控制管理器(SCM) 加以调用。

SCM是操作系统的集成部分,负责响应系统启动以开始服务、指导用户控制或从另一个服务中来的请求。

其本身负责使应用程序的行为像一个服务。

通常,服务登录到特殊的LocalSystem账号下,此账号具有与开发人员创建的服务不同的权限。

当令C++ 编译器创建可执行程序时,编译器将源代码编译成OBJ文件,然后将其与标准库相链接。

产生的EXE文件是装载器指令、机器指令和应用程序的数据的集合。

装载器指令告诉系统从哪里装载机器代码。

另一个装载器指令告诉系统从哪里开始执行进程的主线程。

在进行某些设置后,进入开发者提供的main() 、ServiceMain() 或WinMain() 函数的低级入口点。

操作系统实验指导书

操作系统实验指导书

操作系统实验指导书实验概述本次操作系统实验是为了让学生通过实践了解操作系统的基本概念,原理和使用。

通过完成实验,学生将了解操作系统内核,进程调度,文件系统和输入输出等关键组成部分。

实验环境实验要求使用 Linux 操作系统,可以选择任意一种 Linux 发行版。

可以在物理机上安装 Linux,也可以使用虚拟机软件(如 VirtualBox)来运行 Linux 虚拟机。

实验准备在进行实验之前,需要完成以下准备工作:1.安装 Linux 操作系统(如 Ubuntu、Fedora 等)或虚拟机软件(如VirtualBox)。

2.熟悉 Linux 基本命令和操作,包括文件操作、进程管理等。

实验内容本次操作系统实验分为以下几个部分:1. 实验一:进程管理本部分实验要求学生了解进程管理的基本概念和原理,掌握进程创建、终止和状态转换等操作。

学生需要完成以下任务:•编写一个简单的 C 程序,实现进程的创建、终止和状态转换功能。

•使用 Linux 命令行工具编译、运行和调试 C 程序。

•观察和分析进程的状态转换过程。

2. 实验二:进程调度本部分实验要求学生了解进程调度算法的原理和实现方法,掌握优先级调度、轮转调度和最短作业优先调度等算法。

学生需要完成以下任务:•编写一个简单的 C 程序,模拟进程调度算法的执行过程。

•使用 Linux 命令行工具编译、运行和调试 C 程序。

•观察和分析不同调度算法对进程执行顺序的影响。

3. 实验三:文件系统本部分实验要求学生了解文件系统的基本概念和实现原理,掌握文件的创建、读写和删除等操作。

学生需要完成以下任务:•编写一个简单的 C 程序,实现文件的创建、读写和删除功能。

•使用 Linux 命令行工具编译、运行和调试 C 程序。

•观察和分析文件系统的存储结构和操作过程。

4. 实验四:输入输出本部分实验要求学生了解操作系统的输入输出机制和设备驱动程序的原理和实现方法,掌握文件读写、设备驱动和错误处理等操作。

操作系统教程实验指导书

操作系统教程实验指导书

操作系统教程实验指导书目录实验一WINDOWS进程初识 (4)1、实验目的 (4)2、实验内容和步骤 (4)3、实验结论 (5)4、程序清单 (5)实验二进程管理 (8)背景知识 (8)1、实验目的 (11)2、实验内容和步骤 (11)3、实验结论 (13)4、程序清单 (13)实验三进程同步的经典算法 (18)背景知识 (18)1、实验目的 (19)2、实验内容和步骤 (19)3、实验结论 (20)4、程序清单 (21)实验四存储管理 (25)背景知识 (25)1、实验目的 (29)2、实验内容和步骤 (29)3、实验结论 (35)4、程序清单 (35)实验五文件和设备管理 (40)背景知识 (40)1、实验目的 (42)2、实验内容与步骤 (42)3、实验结论 (45)试验六文件系统设计试验 (46)1、试验目的 (46)2、实验内容与步骤 (46)3、实验结论 (46)4、对试验的改进以及效果 (47)附录A:参考程序 (49)附录B:文件系统模拟程序 (52)52实验一WINDOWS进程初识1、实验目的(1)学会使用VC编写基本的Win32 Consol Application(控制台应用程序)。

(2)掌握WINDOWS API的使用方法。

(3)编写测试程序,理解用户态运行和核心态运行。

2、实验内容和步骤(1)编写基本的Win32 Consol Application步骤1:登录进入Windows,启动VC++ 6.0。

步骤2:在“FILE”菜单中单击“NEW”子菜单,在“projects”选项卡中选择“Win32 Consol Application”,然后在“Project name”处输入工程名,在“Location”处输入工程目录。

创建一个新的控制台应用程序工程。

步骤3:在“FILE”菜单中单击“NEW”子菜单,在“Files”选项卡中选择“C++ Source File”, 然后在“File”处输入C/C++源程序的文件名。

OS操作系统课程实验指导书附运行截图

OS操作系统课程实验指导书附运行截图

OS操作系统课程实验指导书附运行截图实验1使用动态优先权的进程调度算法的模拟1、实验目的(1)加深对进程概念的理解(2)深入了解系统如何组织进程,创建进程(3)进一步认识如何实现处理机调度2、实验内容(1)实现对N个进程采用动态优先权优先算法的进程调度。

(2)每个用来标识进程的进程控制块PCB用结构来描述,包括以下字段:进程标识数ID。

进程优先数PRIORITY,并规定优先数越大的进程,其优先权越高。

进程已占用的CPU时间CPUTIME。

进程还需占用的CPU时间ALLTIME。

当进程运行完毕时,ALLTIME变为0。

进程的阻塞时间STARTBLOCK,表示当进程再运行STARTBLOCK 个时间片后,将进入阻塞状态。

进程被阻塞的时间BLOCKTIME,表示已阻塞的进程再等待BLOCKTIME个时间片后,将转换成就绪状态。

进程状态STATE。

队列指针NEXT,用来将PCB排成队列。

(3)优先数改变的原则:进程在就绪队列中停留一个时间片,优先数加1。

进程每运行一个时间片,优先数减3。

(4)假设在调度前,系统中有5个进程,它们的初始状态如下:ID 0 1 2 3 4PRIORITY 9 38 30 29 0CPUTIME 0 0 0 0 0ALLTIME 3 3 6 3 4STARTBLOCK 2 -1 -1 -1 -1BLOCKTIME 3 0 0 0 0STATE ready ready ready ready ready(5)为了清楚的观察各进程的调度过程,程序应将每个时间片内的情况显示出来,参照的具体格式如下:RUNNING PROG:i READY-QUEUE:->id1->id2BLOCK-QUEUE:->id3->id4= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = == = =ID 0 1 2 3 4PRIORITY P0 P1 P2 P3 P4CUPTIME C0 C1 C2 C3 C4ALLTIME A0 A1 A2 A3 A4STARTBLOCK T0 T1 T2 T3 T4BLOCKTIME B0 B1 B2 B3 B4STATE S0 S1 S2 S3 S43、实验结果(给出编写的程序源代码和运行结果的截图)【程序代码】#include#include#define N 5// 进程状态enum STATE { Ready, Run, Block, Finish };// PCB数据结构struct PCB {int id; // 标志数int priority; // 优先数int cpuTime; // 已占CPU时间int allTime; // 还需占CPU时间int blockTime; // 已被阻塞的时间int startBlock; // 开始阻塞时间STATE state; // 进程状态PCB *pre; // PCB的前指针PCB *nxt; // PCB的后指针};int id[N] = {0, 1, 2, 3, 4};int priority[N] = {9, 38, 30, 29, 0};int cpuTime[N] = {0, 0, 0, 0, 0};int allTime[N] = {3, 3, 6, 3, 4};int startBlock[N] = {2, -1, -1, -1, -1};int blockTime[N] = {3, 0, 0, 0, 0};void QuePush(PCB *process, PCB *queHead){process->pre = NULL;process->nxt = queHead->nxt;if (queHead->nxt != NULL) {queHead->nxt->pre = process;}queHead->nxt = process;}void quePop(PCB *process, PCB *queHead){if (process->pre != NULL) {process->pre->nxt = process->nxt;} else {queHead->nxt = process->nxt;}if (process->nxt != NULL) {process->nxt->pre = process->pre;}process->pre = process->nxt = NULL;}void queWalk(PCB *queHead){PCB *pro = queHead->nxt;if (pro == NULL) {printf("(没有进程啦)\");return;}while (pro != NULL){printf("id: %d, priority: %d, cpuTime: %d, alltime: %d,blockTime: %d,state:%d,startblock: %d\", pro->id, pro->priority, pro->cpuTime, pro->allTime, pro->blockTime, pro->state, pro->startBlock);pro = pro->nxt;}}int readyQueNum; // 就绪队列的进程数量PCB readyQueHead; // 就绪队列的头部PCB *readyMaxProcess; // 就绪队列中优先级最高的进程void readyQuePush(PCB *process){readyQueNum ++;process->state = Ready;QuePush(process, &readyQueHead);}PCB* readyQuePop(){readyQueNum --;quePop(readyMaxProcess, &readyQueHead);return readyMaxProcess;}// 每个时间片,更新就绪队列里进程的信息void readyQueUpdate(){int maxPriority = -1;PCB *pro = readyQueHead.nxt;if (pro == NULL) {// 就绪队列没有进程readyMaxProcess = NULL;return;}while (pro != NULL){pro->priority ++;if (pro->priority > maxPriority) {maxPriority = pro->priority;readyMaxProcess = pro;}pro = pro->nxt;}}// 返回就绪队列最高优先级的值int readyMaxPriority(){return readyMaxProcess->priority;}// 查看就绪队列里进程的信息void readyQueWalk(){printf("就绪队列里的进程信息为:\");queWalk(&readyQueHead);}#define EndBlockTime 3 // 进程最长被阻塞时间int blockQueNum; // 阻塞队列的进程数量PCB blockQueHead; // 阻塞队列的头部PCB *blockMaxProcess; // 阻塞队列中优先级最高的进程// 进程插入到阻塞队列void blockQuePush(PCB *process){blockQueNum ++;process->blockTime = 0;process->state = Block;if (process->blockTime != -1) {QuePush(process, &blockQueHead);}}// 优先级最高的进程出列PCB* blockQuePop(){blockQueNum --;quePop(blockMaxProcess, &blockQueHead);return blockMaxProcess;}// 每个时间片,更新阻塞队列里进程的信息void blockQueUpdate(){int maxPriority = -1;PCB *pro = blockQueHead.nxt;while (pro != NULL){pro->blockTime ++;if (pro->blockTime >= EndBlockTime) {PCB *process = pro;pro = pro->nxt;// 阻塞时间到,调入就绪队列blockQueNum --;quePop(process, &blockQueHead); readyQuePush(process);} else if (pro->priority > maxPriority) {// 更新阻塞队列里优先级最高的进程指针maxPriority = pro->priority; blockMaxProcess = pro;pro = pro->nxt;}}}// 查看阻塞队列里进程的信息void blockQueWalk(){printf("阻塞队列里的进程信息为:\"); queWalk(&blockQueHead);}// 初始化数据void initData(){// 初始化就绪队列和阻塞队列readyQueNum = blockQueNum = 0; readyMaxProcess = blockMaxProcess = NULL;readyQueHead.pre = readyQueHead.nxt = NULL; blockQueHead.pre = blockQueHead.nxt = NULL; // 初始化进程进入就绪队列int i, maxPriority = -1;for (i = 0; i < N; i ++){// 分配一个PCB的内存空间PCB *pro = (PCB *)malloc(sizeof(PCB));// 给当前的PCB赋值pro->id = id[i];pro->priority = priority[i];pro->cpuTime = cpuTime[i];pro->allTime = allTime[i];pro->blockTime = blockTime[i];pro->startBlock = startBlock[i];if (pro->allTime > 0) {// 插入到就绪队列中readyQuePush(pro);// 更新就绪队列优先级最高的进程指针if (pro->priority > maxPriority) {maxPriority = pro->priority; readyMaxProcess = pro;}}}}// 模拟cpu执行1个时间片的操作void cpuWord(PCB *cpuProcess){cpuProcess->priority -= 3;if (cpuProcess->priority < 0) {cpuProcess->priority = 0;}cpuProcess->cpuTime ++;cpuProcess->allTime --;// 显示正执行进程的信息:printf("CPU正执行的进程信息为:\");printf("id: %d, pri: %d, alltime: %d\", cpuProcess->id,cpuProcess->priority, cpuProcess->allTime);}int main(){int timeSlice = 0; // 模拟时间片int cpuBusy = 0; // 模拟cpu状态PCB *cpuProcess = NULL; // 当前在cpu执行的进程initData(); // 初始化// 模拟进程调度while (1){if (readyQueNum == 0 && blockQueNum == 0 && cpuBusy == 0) { // 就绪队列、阻塞队列和cpu无进程,退出break;}if (cpuBusy == 0) {// cpu空闲,选择一个进程进入cpuif (readyQueNum > 0) {// 选择绪队列优先级最高的进程cpuProcess = readyQuePop();} else {// 就绪队列没有进程,改为选择阻塞队列优先级最高的进程cpuProcess = blockQuePop();}cpuProcess->cpuTime = 0;cpuProcess->state = Run;cpuBusy = 1;cpuProcess->startBlock --;}timeSlice ++;printf("\第%d个时间片后:\", timeSlice);// 模拟cpu执行1个时间片的操作cpuWord(cpuProcess);if (cpuProcess->allTime == 0) {cpuProcess->state = Finish;// 释放已完成进程的PCBfree(cpuProcess);cpuBusy = 0;}// 更新就绪队列和阻塞队列里的进程信息blockQueUpdate();readyQueUpdate();// 查看就绪队列和阻塞队列的进程信息readyQueWalk();blockQueWalk();if ((cpuProcess -> startBlock) > 0) {blockQuePush(cpuProcess);cpuProcess = readyQuePop();}else {if (cpuBusy == 1 && readyQueNum > 0 && cpuProcess->priority < readyMaxPriority()){readyQuePush(cpuProcess);cpuProcess = readyQuePop();}}}printf("\模拟进程调度算法结束2145115 刘成路\");return 0;}【运行截图】实验2使用动态分区分配方式的模拟1、实验目的(1)了解动态分区分配方式中使用的数据结构和分配算法(2)加深对动态分区存储管理方式及其实现过程的理解。

《计算机操作系统实验指导》第十——十二章

《计算机操作系统实验指导》第十——十二章

1、添加一个类似ext2的文件系统myext2
(2)修改文件的内容 • 使用编辑器的替换功能,把 /lib/modules/$(uname -r)/build/include/linux/ myext2_fs.h,和/lib/modules/$(uname r)/build/include/asm-generic/bitops/下的 myext2-atomic.h与myext2-atomic-setbit.h文件 中的“ext2”、“EXT2”分别替换成“myext2”、 “MYEXT2”。 • 也可以使用vim进行修改,如图修改 myext2_fs.h文件。
编写一个简单的内核模块
4. 执行内核模块的装入命令 # sudo insmod helloworld.ko 可通过dmesg查看控制台输出,预期结果为<1> Hello World! 还可以使用lsmod命令查看,Ismod命令的作用是列出所有在内核中运行的模块的信息,包括 模块的名称、占用空间的大小、使用计数以及当前状态和依赖性。
5. 当不需要使用该模块时,卸载这个模块。 # sudo rmmod helloworld 可通过dmesg查看控制台输出,预期结果为<1>Goodbye!
利用内核模块实现/proc文件系统
• proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系 统的方式为访问系统内核数据的操作提供接口。用户和应用程序可以通过proc得到系统 的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所 以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出所需信息并提 交的 。
第10章 内核模块
《计算机操作系统实验指导》

操作系统实验指导书2013428

操作系统实验指导书2013428
2、了解并熟悉Linux系统的进程管理,学会进程的查找、查看、撤销(杀死),分析系 统核心资源分配和使用情况等;
3、 通过交互命令的操作实践,了解并熟悉Linux系统的系统功能、文件和网络等的管理 功能和方法;
二、
1、掌握图形界面和字符界面下关机及重启的命令。
2、掌握Linux下获取帮助信息的命令:man info、help以及其他实用程序。
2、Win2000/XP系统的任务管理器
三、
1、编辑、查看、复制、比较和改名等管理;
4、本地网络配置与连接状态等的测试与查看等;
5、打开任务管理器窗口,查看CP呼口存的使用情况;
6、 进程(及活动程序)的查找、查看、撤销(杀死);
7、网络和用户活动情况监控;
《操作系统》
实验指导书
述和编
计算机科学与技术学院
2013年4----6月用
实验一一Win2K交互命令与进程管理1
实验二Linux交互命令3
实验三Linux vi编辑器的使用以及编程实践10
实验四Win2K系统的管理功能13
实验五Linux进程控制与进程通信16
实验六进程调度模拟程序设计20
实验七页面置换模拟程序设计31
#Lfnde1 FOINTVALUE_H
#define FOINTVALUE_H
flnclude ■ Paliitstruct Jr
#Lniclude"lisrh"
axtarr char *^_cPath;
extern Listclass PointListj
int SetPcLntValue(mt 5umfValue0fTinKPQLnt* pdata)
help [-dms]:显示shell的建指令的帮助信息

《操作系统》课程实验指导书

《操作系统》课程实验指导书

操作系统实验指导书梁海英编系部:班级:学号:姓名:淮安信息职业技术学院2009年1月5日实验须知1、实验前,应认真阅读实验指导书,明确实验目的和实验内容,做好实验准备。

2、实验中,积极思考,及时记录,有疑问及时解决,当堂完成实验内容和实验报告。

3、严格遵守实验实管理规则,珍惜实验时间,不做与实验无关的事。

4、实验结束,按要求填写实验机器使用记录单,正确关闭实验用机,整理好键盘和椅子,值日生认真打扫实验室卫生。

5、如实认真填写实验报告相关内容。

目录前言 (1)实验一 (3)实验二 (12)实验三 (21)实验四 (26)实验五 (33)实验六 (37)实验七 (43)实验一进程管理与控制实验日期:实验成绩:一、实验目的进程管理是操作系统多用户与多任务管理的基本重要手段,用户作业与任务进入内存后采用进程模式进行管理,利用不同进程对资源的不同要求实现进程的并发管理是提高系统效率的有效途径。

本实验的目的是要求学生通过实验全面了解进程管理与控制的相关内容,并通过Windows 2000系统中管理控制工具了解常见系统进程,分析系统性能。

二、实验指导与内容任务管理器是Windows系统中一个非常实用的系统工具,它提供了有关计算机性能的信息,并显示了计算机上所运行的程序和进程的详细信息,可以显示最常用的度量进程性能的单位;如果连接到网络,那么还可以查看网络状态并迅速了解网络是如何工作的。

启动任务管理器最常见的方法是同时按下“Ctrl+Alt+Del”组合键,还可以右键单击任务栏的空白处,然后单击选择“任务管理器”命令,或者,按下“Ctrl+Shift+Esc”组合键也可以打开任务管理器,当然,也可以为\Windows\System32\taskmgr.exe文件在桌面上建立一个快捷方式,然后为此快捷方式设置一个热键,以后就可以一键打开任务管理器了。

任务管理器的用户界面提供了文件、选项、查看、窗口、关机、帮助等六大菜单项,其下还有应用程序、进程、性能、联网、用户等五个标签页,窗口底部则是状态栏,从这里可以查看到当前系统的进程数、CPU使用比率、更改的内存、容量等数据,默认设置下系统每隔两秒钟对数据进行1次自动更新,当然你也可以点击“查看→更新速度”菜单重新设置。

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

作系统授课班级:11计本,11网工授课教师:梁宝华目录实验一进程管理 2 实验二存储器管理 9 实验三设备管理 16 实验四文件管理 21 实验五课程设计 27实验一进程管理//以下程序中有些错误,请找出并调试#include <stdio.h>#define TRUE 1#define FALSE 0#define MAXPRI 100#define NIL -1//进程控制块struct {int id; //进程号char status; //进程状态,'e'-执行态'r'-高就绪态't'-低就绪态'w'-等待态'c'-完成态int nextwr; //等待链指针,指示在同一信号量上等待的下一个等待进程的进程号。

int priority; //进程优先数,值越小,优先级越高。

int c;//进程中断次数}pcb[3];//共3个进程//s1、s2为三个进程共享的变量;seed为随机值;registeri模拟寄存器值,存放计算的重复次数。

int registeri,s1,s2,seed,exe=NIL;//exe为当前运行(占有cpu)的进程号//2个信号量sem[0]、sem[1],分别与共享变量s1、s2相联系。

//对应信号量sem[0]、sem[1]分别有两个阻塞队列,队列首由sem[].firstwr指定,队列链指针是pcb[].nextwrstruct{int value;//信号量值int firstwr;//等待该信号量的阻塞队列的首个进程号}sem[2];//三个进程的现场保留区,其中savearea[][0]为寄存器内容,savearea[][1]为下一条指令地址。

char savearea[3][4];char addr;//当前执行程序的当前指针void main();void init();float random();int timeint(char ad);int scheduler();int find();int p(int se,char ad);void block(int se);int v(int se,char ad);void wakeup(int se);void process1();void process2();void process3();void eexit(int n);//--------------------------------------------------------------------//主程序void main(){int currentProcess;printf("进程管理器\n");init();printf("s1=%d,s2=%d\n",s1,s2);printf("进程1、进程2、进程3已经准备好!\n");for (;;){currentProcess=scheduler(); //进程调度,选择优先级别最高的就绪进程运行。

if (currentProcess==NIL)break; //所有进程已经运行完毕,结束。

switch (currentProcess) //运行当前进程代码{case 0:break;case 1:process2();break;case 2:process3();break;default:printf("进程号出错!\n");break;}}printf("最后结果:s1=%d,s2=%d\n",s1,s2);}//------------------------------------------------------------------------ //初始化void init(){int i,j;s1=0;s2=0;//生成进程控制块for (j=0;j<3;j++){pcb[j].id=j; //进程号pcb[j].status='r'; //进程初始状态为高就绪状态pcb[j].nextwr=NIL;printf("\n进程%d 的优先数?",j+1);scanf("%d",&i);pcb[j].priority=i; //进程优先级pcb[j].c=0;}//初始化两个信号量sem[0].value=1;//与s1相联系sem[0].firstwr=NIL;sem[1].value=1;//与s2相联系sem[1].firstwr=NIL;//初始化现场保留区。

每个进程均有现场保留区。

for (i=1;i<3;i++)for (j=0;j<4;j++)savearea[i][j]='0';} //end of init()//生成0~1之间随机值float random(){int m;if (seed<0) m=-seed;else m=seed;seed=(25173*seed+13849)%65536;return (m/32767.0);}//----------------------------------------------------------------------------------//检测当前进程的时间片是否已到。

未到,返回FALSE,否则返回TRUE。

系统采用分时执行,//规定每个进程的执行概率为33%,用产生数x模拟时间片。

//ad为程序的当前语句地址。

int timeint(char ad){float x;x=random();if ((x<0.33)&&(exe==0)) return (FALSE);//当前进程为进程1,时间片未到。

if ((x>=0.33)&&(x<0.66)&&(exe==1)) return (FALSE);//当前进程为进程2,时间片未到。

if ((x>=0.66)&&(x<1)&&(exe==2)) return (FALSE);//当前进程为进程3,时间片未到。

//时间片已到处理:置正在执行进程状态为低就绪,处理器空闲。

savearea[exe][0]=registeri;//保存通用寄存器内容savearea[exe][1]=ad;//保存程序指针pcb[exe].status='t';//状态改为低就绪态printf("时间片中断,进程%d转入就绪态\n",exe+1);exe=NIL;return (TRUE);}//-----------------------------------------------------------------------------------//进程调度:选择一个进程投入运行。

返回当前进程的进程号。

int scheduler(){int pd;//选择投入运行的进程pdif ((pd=find())==NIL && exe==NIL)return (NIL);//无进程可运行,将结束。

if (pd!=NIL){if (exe==NIL) //选中了进程且处理器空闲,则投入运行。

{pcb[pd].status='e';exe=pd;printf("进程%d正在执行\n",exe+1);}else if (pcb[pd].priority<pcb[exe].priority)//选中进程的优选级别高于当前进程{//将当前进程转入高就绪状态pcb[exe].status='r';printf("进程%d进入就绪状态\n",exe+1);//选中进程pd投入执行pcb[pd].status='e';exe=pd;printf("进程%d正在执行\n",exe+1);}}//恢复进程现场registeri=savearea[exe][0];//恢复当前进程的寄存器。

addr=savearea[exe][1];//恢复执行进程的程序指针//修改优先权if(pcb[pd].c==3){pcb[pd].c=0;pcb[pd].priority=0;printf("\n!!进程%d中断次数达到3,优先级提高\n",pd+1);}return (exe);//返回当前进程的进程号}//---------------------------------------------------------------------------------//在3个进程中按就绪状态及其优先数选出进程。

返回选出的进程号。

int find(){int j,pd=NIL,w=MAXPRI;for (j=0;j<3;j++) //选择高就绪状态优先级最高的进程{if ((pcb[j].status=='r') && (pcb[j].priority<w)){w=pcb[j].priority;pd=j;}}if (pd==NIL) //没有高就绪状态的进程,寻找低就绪状态的进程。

{for (j=0;j<3;j++){if ((pcb[j].status=='t') && (pcb[j].priority<w)){w=pcb[j].priority;}}}return (pd);}//--------------------------------------------------------------------------------------//P操作,申请资源。

若申请se号资源成功,返回FALSE,若失败,把当前进程挂入se号资源的阻塞队列,//让出cpu,返回TRUE.//se为资源号,ad为程序当前指令的地址。

int p(int se,char ad){if (--sem[se].value>=0)return (FALSE);//资源申请成功//资源申请失败处理:block(se);//把当前进程挂入se号资源的阻塞队列savearea[exe][0]=registeri;//保存当前进程的寄存器内容savearea[exe][1]=ad;//保存当前进程的下一条指令地址exe=NIL;//让出CPUreturn (TRUE);//资源申请失败}//----------------------------------------------------------------------------//把当前进程阻塞,并挂到资源se的阻塞队列。

相关文档
最新文档