操作系统中级模块实验三
操作系统实验报告3
![操作系统实验报告3](https://img.taocdn.com/s3/m/f9790f78580102020740be1e650e52ea5418ce45.png)
操作系统实验报告3一、实验目的本次操作系统实验的主要目的是深入了解和掌握操作系统中进程管理、内存管理以及文件系统等核心概念和相关技术,并通过实际的实验操作,提高对操作系统原理的理解和应用能力。
二、实验环境本次实验使用的操作系统为 Windows 10,开发工具为 Visual Studio 2019。
三、实验内容及步骤(一)进程管理实验1、创建进程使用 C++语言编写程序,通过调用 Windows API 函数`CreateProcess`来创建一个新的进程。
在创建进程时,设置进程的优先级、环境变量等参数,并观察进程的创建过程和相关的系统资源使用情况。
```cppinclude <windowsh>include <iostream>int main(){STARTUPINFO si;PROCESS_INFORMATION pi;ZeroMemory(&si, sizeof(si));sicb = sizeof(si);ZeroMemory(&pi, sizeof(pi));//设置进程的优先级为 HIGH_PRIORITY_CLASS DWORD priorityClass = HIGH_PRIORITY_CLASS;//创建进程if (!CreateProcess(NULL, //应用程序名称"notepadexe",//命令行参数NULL, //进程安全性NULL, //线程安全性FALSE, //不继承句柄priorityClass, //进程优先级NULL, //环境变量NULL, //当前目录&si,&pi)){std::cout <<"CreateProcess failed Error code: "<<GetLastError()<< std::endl;return 1;}//等待进程结束WaitForSingleObject(pihProcess, INFINITE);//关闭进程和线程的句柄CloseHandle(pihProcess);CloseHandle(pihThread);return 0;}```2、进程同步与互斥编写一个多线程程序,模拟生产者消费者问题。
操作系统实验报告三
![操作系统实验报告三](https://img.taocdn.com/s3/m/813d67a9e109581b6bd97f19227916888486b9ec.png)
操作系统实验报告三一、实验目的本次实验的目的是通过设计和实现一个简单的操作系统,加深对操作系统内核设计的理解,并学习操作系统内核的基本构建和运行原理。
二、实验背景操作系统是计算机系统中最核心的软件之一,它负责管理计算机的各种资源以及协调和控制应用程序的执行。
操作系统的设计和实现使计算机能够高效地运行并提供友好的用户接口。
操作系统也为应用程序提供了统一的软硬件访问接口,方便开发人员进行软件开发。
操作系统的设计和实现是计算机科学与技术领域中重要的研究方向之一。
通过操作系统的实验,可以深入了解操作系统的内部原理和机制,加深对操作系统的理解和认识。
三、实验内容本次实验需要设计和实现一个简单的操作系统,完成以下功能:1. 实现一个简单的内存管理模块,包括内存分配和释放的功能。
2. 实现一个简单的进程管理模块,包括进程的创建、撤销和切换的功能。
3. 实现一个简单的文件系统模块,包括文件的读写和目录的管理功能。
4. 实现用户与操作系统之间的交互界面,方便用户进行操作系统的使用。
四、实验步骤1. 设计和实现内存管理模块:a. 设计内存分配算法,根据系统的需要分配和释放内存空间。
b. 实现内存分配和释放的功能函数,确保能够正确地分配和释放内存空间。
2. 设计和实现进程管理模块:a. 设计进程控制块(PCB),记录进程的相关信息。
b. 实现进程的创建、撤销和切换的功能函数,确保进程能够正确地被创建、撤销和切换。
3. 设计和实现文件系统模块:a. 设计文件控制块(FCB),记录文件的相关信息。
b. 实现文件的读写和目录的管理功能函数,确保文件能够正确地被读写和目录能够正确地被管理。
4. 实现用户与操作系统之间的交互界面:a. 设计用户界面,包括命令解释器等。
b. 实现用户输入命令的解释和执行函数,确保用户能够正确地与操作系统进行交互。
五、实验结果与分析经过实验,我们成功地设计和实现了一个简单的操作系统,并完成了内存管理、进程管理和文件系统的功能实现。
操作系统 实验三 进程同步
![操作系统 实验三 进程同步](https://img.taocdn.com/s3/m/e8abd0f60242a8956bece493.png)
集美大学计算机工程学院实验报告课程名称:操作系统指导教师:王丰实验成绩:实验编号:实验三实验名称:进程同步班级:计算12姓名:学号:上机实践日期:2015.5上机实践时间:2学时一、实验目的1、掌握用Linux信号灯集机制实现两个进程间的同步问题。
2、共享函数库的创建二、实验环境Ubuntu-VMware、Linux三、实验内容⏹需要的信号灯: System V信号灯实现☐用于控制司机是否可以启动车辆的的信号灯 S1=0☐用于控制售票员是否可以开门的信号灯 S2=0System V信号灯实现说明□ System V的信号灯机制属于信号灯集的形式, 一次可以申请多个信号灯.□同样利用ftok()生成一个key: semkey=ftok(path,45);□利用key申请一个包含有两个信号灯的信号灯集, 获得该集的idsemid=semget(semkey,2,IPC_CREAT | 0666);□定义一个联合的数据类型union semun{int val;struct semid_ds *buf;ushort *array;};□利用semctl()函数对信号灯初始化,参数有:信号灯集的id: semid要初始化的信号灯的编号:sn要设定的初始值:valvoid seminit(int semid, int val,int sn){union semun arg;arg.val=val;semctl(semid,sn,SETVAL,arg);}利用初始化函数,初始化信号灯:seminit(semid,0,0);//用来司机启动汽车的同步seminit(semid,0,1);//用来售票员开门的同步控制□利用semop()函数, 对信号灯实现V操作:sembuf是一个在头部文件中的预定义结构、semid—信号灯集id, sn—要操作的信号灯编号void semdown(int semid,int sn){/* define P operating*/struct sembuf op;op.sem_num=sn;op.sem_op=-1;//P操作为-1op.sem_flg=0;semop(semid,&op,1);}2、Linux的静态和共享函数库·Linux生成目标代码: gcc -c 源程序文件名(将生成一个与源程序同名的.o目标代码文件。
操作系统实验三
![操作系统实验三](https://img.taocdn.com/s3/m/e4e20944336c1eb91a375d9d.png)
操作系统实验报告计算机0703班200729实验3 进程同步和通信-生产者和消费者问题模拟1. 目的:调试、修改、运行模拟程序,通过形象化的状态显示,使学生理解进程的概念,了解同步和通信的过程,掌握进程通信和同步的机制,特别是利用缓冲区进行同步和通信的过程。
通过补充新功能,使学生能灵活运用相关知识,培养创新能力。
2. 内容及要求:1) 调试、运行模拟程序。
2) 发现并修改程序中不完善的地方。
3) 修改程序,使用随机数控制创建生产者和消费者的过程。
4) 在原来程序的基础上,加入缓冲区的写互斥控制功能,模拟多个进程存取一个公共缓冲区,当有进程正在写缓冲区时,其他要访问该缓冲区的进程必须等待,当有进程正在读取缓冲区时,其他要求读取的进程可以访问,而要求写的进程应该等待。
5) 完成1)、2)、3)功能的,得基本分,完成4)功能的加2分,有其它功能改进的再加2分3. 程序说明:本程序是模拟两个进程,生产者(producer)和消费者(Consumer)工作。
生产者每次产生一个数据,送入缓冲区中。
消费者每次从缓冲区中取走一个数据。
缓冲区可以容纳8个数据。
因为缓冲区是有限的,因此当其满了时生产者进程应该等待,而空时,消费者进程应该等待;当生产者向缓冲区放入了一个数据,应唤醒正在等待的消费者进程,同样,当消费者取走一个数据后,应唤醒正在等待的生产者进程。
就是生产者和消费者之间的同步。
每次写入和读出数据时,都将读和写指针加一。
当读写指针同样时,又一起退回起点。
当写指针指向最后时,生产者就等待。
当读指针为零时,再次要读取的消费者也应该等待。
为简单起见,每次产生的数据为0-99的整数,从0开始,顺序递增。
两个进程的调度是通过运行者使用键盘来实现的。
4. 程序使用的数据结构进程控制块:包括进程名,进程状态和执行次数。
缓冲区:一个整数数组。
缓冲区说明块:包括类型,读指针,写指针,读等待指针和写等待指针。
5. 程序使用说明启动程序后,如果使用'p'键则运行一次生产者进程,使用'c'键则运行一次消费者进程。
操作系统实验报告3
![操作系统实验报告3](https://img.taocdn.com/s3/m/beb7fc16eff9aef8941e0695.png)
操作系统实验3报告学号:姓名:专业:计算机科学与技术(普通班)操作系统实验 3实验内容:1、消息的创建、发送和接收:使用系统调用msgget()、msgsnd()、msgrev()、msgctl()编制一个对长度1K的消息进行发送和接收的程序。
〈程序设计〉(1)为了便于操作和观察结果,用一个程序作为“引子”,先后fork( )两个子进程,SERVER和CLIENT,进行通信。
(2)SERVER端建立一个Key为75的消息队列,等待其他进程发来的消息。
当遇到类型为1的消息,则作为结束信号,取消该队列,并退出SERVER。
SERVER每接收到一个消息后显示一句“(server) received”。
(3)CLIENT端使用Key为75的消息队列,先后发送类型从10到1的消息,然后退出。
最后的一个消息,即是SERVER端需要的结束信号。
CLIENT每发送一条消息后显示一句“(client) sent”。
(4)父进程在SERVER和CLIENT均退出后结束。
〈程序〉# include <stdio.h># include <sys/types.h># include <sys/msg .h># include <sys/ipc.h># define MSGKEY 75 /*定义关键词MSGKEY*/struct msgform/*消息结构*/{long mtype ;char mtext[1030] ;/*文本长度*/} msg ;int msgqid , i ;void CLIENT( ){int i ;msgqid = msgget(MSGKEY , 07777) ;for(i = 10 ; i>= 1 ; i--){msg . mtype = I ;printf (“(client) sent\n”) ;msgsnd (msgqid , &msg , 1024 , 0) ;/*发送消息msg入msgqid消息队列*/}exit(0) ;}void SERVER( ){msgqid = msgget(MSGKEY , 0777 | IPC_CREAT) ;/*由关键字获得消息队列*/do{msgrev (msgqid , &msg , 1030 , 0 , 0) ;/*从msgqid队列接收消息msg */printf (“(server) received\n”) ;}while (msg . mtype != 1) ;/*消息类型为1时,释放队列*/msgctl (msgqid , IPC_RMID , 0) ;exit (0) ;}void main ( ){while ((i = fork ( )) = = -1) ;if (! i ) SERVER( ) ;while ((i = fork ( )) = = -1) ;if (! i ) CLIENT( ) ;wait (0) ;wait (0) ;}〈结果〉2、共享存储区的创建,附接和断接使用系统调用shmget()、shmat ()、shmdt ()、shmctl()编制一个与上述功能相同的程序。
操作系统实验三实验报告
![操作系统实验三实验报告](https://img.taocdn.com/s3/m/c57c1a47640e52ea551810a6f524ccbff121cac7.png)
(一)进程创建
编写程序实现创建多个进程,并观察进程的执行情况。通过调用Windows API函数`CreateProcess`来创建新的进程。在创建进程时,设置不同的参数,如进程的优先级、命令行参数等,观察这些参数对进程执行的影响。
(二)进程控制
实现对进程的暂停、恢复和终止操作。使用`SuspendThread`和`ResumeThread`函数来暂停和恢复进程中的线程,使用`TerminateProcess`函数来终止进程。通过控制进程的执行状态,观察系统的资源使用情况和进程的响应。
(一)进程创建实验结果与分析
创建多个进程后,通过任务管理器观察到新创建的进程在系统中运行。不同的进程优先级设置对进程的CPU占用和响应时间产生了明显的影响。高优先级的进程能够更快地获得CPU资源,执行速度相对较快;而低优先级的进程则在CPU资源竞争中处于劣势,可能会出现短暂的卡顿或计一个多进程同步的程序,使用信号量、互斥量等同步机制来协调多个进程的执行。例如,实现一个生产者消费者问题,多个生产者进程和消费者进程通过共享缓冲区进行数据交换,使用同步机制来保证数据的一致性和正确性。
四、实验步骤
(一)进程创建实验步骤
1、打开Visual Studio 2019,创建一个新的C++控制台应用程序项目。
六、实验中遇到的问题及解决方法
(一)进程创建失败
在创建进程时,可能会由于参数设置不正确或系统资源不足等原因导致创建失败。通过仔细检查参数的设置,确保命令行参数、环境变量等的正确性,并释放不必要的系统资源,解决了创建失败的问题。
(二)线程控制异常
在暂停和恢复线程时,可能会出现线程状态不一致或死锁等异常情况。通过合理的线程同步和错误处理机制,避免了这些异常的发生。在代码中添加了对线程状态的判断和异常处理的代码,保证了线程控制的稳定性和可靠性。
操作系统实验3
![操作系统实验3](https://img.taocdn.com/s3/m/72699af1534de518964bcf84b9d528ea81c72f96.png)
操作系统实验3青岛科技⼤学实验报告2013年10 ⽉24⽇姓名王茂林专业集成电路班级 111班同组者课程操作系统实验项⽬试验3:进程的控制与互斥⼀、实验⽬的:1、掌握在⼦进程中使⽤execl()执⾏系统命令或调⽤其它已编译的可执⾏程序。
2、掌握⽗进程通过创建⼦进程完成某项任务的⽅法。
3、掌握系统调⽤exit()和_exit()的使⽤。
4、进⼀步理解进程并发执⾏的实质。
5、学习系统调⽤sleep()的使⽤⽅法。
6、学习系统调⽤lockf()的使⽤⽅法。
7、分析进程竟争资源的现象,学习解决进程互斥的⽅法。
⼆、实验内容:1、设计程序实现⽗进程创建多个⼦进程,⼦进程使⽤execl()函数调⽤已编译的其他可执⾏程序。
2、运⾏实验指导书32页程序,分析程序执⾏结果。
3、设计⼀程序,⽗进程创建⼀个⽂本⽂件,多个⼦进程利⽤系统调⽤lockf()实现对该⽂件进⾏互斥读或写操作。
三、实验步骤及结果:1、启动windows下已经安装好的VMware虚拟机进⼊linux系统2、等待系统初始化完毕后启动命令终端3、阅读实验指导书4、运⾏以下程序,分析程序运⾏结果。
运⾏程序如下:# include# include#include# includemain(){int p;printf("this is parent1");p=fork();if(p>0)printf("this is parent2");else{printf("this is child first\n");printf("this is child second");_exit(0);}}写⼊如下命令:执⾏后,将打开⽂本编辑器gedit书写如下源代码,保存。
编译运⾏后出现如下结果:在以上程序中,若将_exit(0)换为exit(0),运⾏结果为:原因:系统调⽤exit()和_exit()作⽤为使进程⾃动退出系统,他们的区别如下: exit():终⽌调⽤进程的执⾏。
操作系统实验三
![操作系统实验三](https://img.taocdn.com/s3/m/8535a51925c52cc58bd6bebd.png)
实验三进程的创建一、实验目的·练习使用EOS API 函数CreateProcess 创建一个进程,掌握创建进程的方法,理解进程和程序的区别。
·调试跟踪CreateProcess 函数的执行过程,了解进程的创建过程,理解进程是资源分配的基本单位。
·调试跟踪CreateThread 函数的执行过程,了解线程的创建过程,理解线程是调度的基本单位。
二、实验内容1、执行了实验指导书3.2的步骤,学习到了如何使用控制台命令创建一个EOS应用程序的进程,结果如下图所示。
2、执行了实验指导书3.3的步骤,学习到了如何使用控制台命令创建一个EOS应用程序的进程,结果如下图所示。
3、执行了实验指导书3.4的步骤,观察到了系统中有三个进程,其中第一个是系统进程,镜像名称为空;另外两个是刚刚创建的应用程序的进程,镜像名称分别为“A:\EOSApp.exe”和“A:\Hello.exe”。
其中,A:\EOSApp.exe进程是父进程,其主线程处于运行状态;A:\Hello.exe 进程是子进程,其主线程处于就绪状态,当父进程的主线程通过调用WaitForSingleObject 函数进入阻塞状态让出处理器后,这个处于就绪状态的线程就会占用处理器开始运行。
这两个应用程序的进程和线程的优先级都为8。
说明了处于阻塞队列的进程等到I/O完成后按照优先级策略排成就绪队列,等到获得CPU后便可立即执行。
4、执行了实验指导书3.5的步骤,观察到了用于存储内核管理的数据,已经使用的虚拟地址空间都大于0x80000000,说明了内核在4G 虚拟地址空间;观察到了CreateProcess 函数中所有指令的虚拟地址都是大于0x80000000 的,验证了内核程序(kernel.dll)位于高2G 虚拟地址空间;观察到了“反汇编”窗口中main 函数所有指令的虚拟地址都是小于0x80000000 的,说明应用程序(eosapp.exe)位于低2G 的虚拟地址空间中;观察到了调试PspCreateProcessEnvironment 函数时*NewProcess 的值的变化情况,了解了各个成员变量的初始化情况;用NewTwoProc.c 文件中的源代码替换EOS 应用程序项目中EOSApp.c 文件内的源代码,生成后启动调试,查看多个进程并发执行的结果如图所示,了解了通过编程的方式创建一个应用程序的多个进程。
操作系统实验三 指导书
![操作系统实验三 指导书](https://img.taocdn.com/s3/m/d3e40d2143323968011c9226.png)
实验三操作系统中的经典线程同步问题一、实验目的1、加深对线程的理解、掌握Windows中线程的操作。
2、掌握死锁产生的原因。
3、掌握信号量、互斥量、事件、临界区等同步对象的使用。
二、实验理论基础及教材对应关系1、进程和线程的关系。
2、线程间的同步和通信。
3、本实验内容主要对应于教材第4、5、6、7章三、实验内容与步骤1、运行实验程序“运行.exe”,出现如下界面:2、点击运行读者-写者程序按钮,出现如下界面:选择a 或b操作,进行实验,观察结果的输出。
3、观察第二步的实验现象,多次试验,可总结为:(1)、选择a操作和b操作的输出结果的区别是。
(2)、修改目录“data”中的“yanzheng.txt”文档中的数据,观察执行a 操作和b操作之后有什么变化,说明“yanzheng.txt”文档中各列数据的含义是什么。
(3)、这说明“读者”间的关系是、“写者”之间的关系是、“读者-写者”之间的关系是。
(填相容、互斥)4、点击实验界面上的“运行duozhe-xiezhe.cpp”按钮,查找并说明下列函数的用法:(1) CreateThread();(2)CreateMutex();(3)ReleaseMutex();(4) WaitForSingleObject();5、运行“DiningPhilosophor”目录中的项目程序,观察程序运行结果,查看项目源文件,进一步学习线程的同步与死锁。
观察线程间“死锁”时的状态。
深入分析死锁产生的原因:。
6、创建一个“Console”应用程序,在main()函数中创建4个线程,线程的工作就是向屏幕输出几个字符后,就自己结束掉。
(1)程序源码。
(2)程序运行结果截图。
(3)实验过程与结果分析。
四、实验材料的提交与成绩评定1、本实验的实验报告一份(电子版或纸质版一份,具体形式由任课教师确定,格式参考学院统一实验报告)。
操作系统experiment3
![操作系统experiment3](https://img.taocdn.com/s3/m/c70265fe941ea76e59fa0404.png)
实验2 存储管理1. 实验目的存储管理的主要功能之一是合理地分配空间,请求页式管理式一种常用的虚拟存储管理技术。
本实验的目的是通过请求页式管理中页面置换算法的模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。
2. 实验内容(1) 通过随机数产生一个指令序列,共320条指令,指令地址按下述原则生成①50%的指令是顺序执行;②25%的指令是均匀分布在前地址部分;③25%的指令是均匀分布在后地址部分;具体的实施方法是①在[0, 319] 的指令地址之间随机选取一起点m ;②顺序执行一条指令,即执行地址为m+1 的指令;③在前地址[0, m+1] 中随机选取一条指令并执行,该指令的地址是m’;④顺序执行一条指令,其地址为m’+1 ;⑤在后地址[m’+2, 319] 中随机选取一条指令并执行;⑥重复上述步骤①~⑤,直到执行320次指令。
(2) 将指令序列变为页地址流设:①页面大小为1K ;②用户页面内存容量为4页到32页;③用户虚存容量为32K 。
在用户虚存中,按每K 存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:第0条~第9条指令为第0页(对应虚存地址为[0, 9]);第10条~第19条指令为第1页(对应虚存地址为[10, 19]);…………第310条~第319条指令为第31页(对应虚存地址为[310, 319]);按以上方式,用户指令可组成32页。
(3) 计算并输出下述各种算法在不同内存容量下的命中率①First-In-First-out (FIFO) Page Replacement②Least-Recently-Used (LRU) Page Replacement③Optimal Page Replacement其中③和④为选择内容页地址流长度页面失效次数-命中率= 1在本实验中,页地址流长度为320,页面失效次数为每次访问相应指令时,该指令所对应的页不在内存的次数。
操作系统实验三
![操作系统实验三](https://img.taocdn.com/s3/m/e74d43d510661ed9ac51f342.png)
实验三进程调度实验目的1、理解有关进程控制块、进程队列的概念。
2、掌握进程优先权调度算法和时间片轮转调度算法的处理逻辑。
实验内容与基本要求1、设计进程控制块PCB的结构,分别适用于优先权调度算法和时间片轮转调度算法。
2、建立进程就绪队列。
3、编制两种进程调度算法:优先权调度算法P和时间片轮转调度算法R。
实验报告内容1、优先权调度算法和时间片轮转调度算法原理。
2、程序流程图。
3、程序及注释。
4、运行结果以及结论。
1、优先权调度算法和时间片轮转调度算法原理优先权调度算法:当该算法用于作业调度时,系统从后备作业队列中选择若干个优先级最高的,且系统能满足资源要求的作业装入内存运行;当该算法用于进程调度时,将把处理机分配给就绪进程队列中优先级最高的进程投入运行。
分为非抢占式优先级算法和抢占式优先级算法。
时间片轮转调度算法原理:系统将就绪进程按到达的顺序排成一个队列,按FCFS原则,进程调度程序总是选择就绪队列中的第一个进程执行,且只运行一个时间片。
时间用完后,即使此进程并未完成,仍然将处理机分配给下一个就绪的进程,将此进程返回到就绪队列的末尾,等候重新运行。
2、程序流程图。
3、程序及注释#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct node{char name[20]; /*进程的名字*/int prio; /*进程的优先级*/int round; /*分配CPU的时间片*/int cputime; /*CPU执行时间*/int needtime; /*进程执行所需要的时间*/char state; /*进程的状态,W--就绪态,R--执行态,F--完成态*/int count; /*记录执行的次数*/struct node *next; /*链表指针*/}PCB;PCB *ready=NULL,*run=NULL,*finish=NULL; /*定义三个队列,就绪队列,执行队列和完成队列*/int num;void GetFirst(); /*从就绪队列取得第一个节点*/void Output(); /*输出队列信息*/void InsertPrio(PCB *in); /*创建优先级队列,规定优先数越小,优先级越高*/void InsertTime(PCB *in); /*时间片队列*/void InsertFinish(PCB *in); /*时间片队列*/void PrioCreate(); /*优先级输入函数*/void TimeCreate(); /*时间片输入函数*/void Priority(); /*按照优先级调度*/void RoundRun(); /*时间片轮转调度*/int main(void){char chose;printf("请输入要创建的进程数目:\n");scanf("%d",&num);getchar();printf("输入进程的调度方法:(P/R)\n");scanf("%c",&chose);switch(chose){case 'P':case 'p':PrioCreate();Priority();break;case 'R':case 'r':TimeCreate();RoundRun();break;default:break;}Output();return 0;}void GetFirst() /*取得第一个就绪队列节点*/{run = ready;if(ready!=NULL){run ->state = 'R';ready = ready ->next;run ->next = NULL;}}void Output() /*输出队列信息*/{PCB *p;/*p = ready;*/printf("进程名\t优先级\t时间片\tcpu时间\t需要时间\t进程状态\t计数器\n");p = ready;while(p!=NULL){printf("%s\t%d\t%d\t%d\t%d\t\t%c\t\t%d\n",p->name,p->prio,p->round,p->cputime,p->needtime, p->state,p->count);p = p->next;}p = finish;while(p!=NULL){printf("%s\t%d\t%d\t%d\t%d\t\t%c\t\t%d\n",p->name,p->prio,p->round,p->cputime,p->needtime, p->state,p->count);p = p->next;}p = run;while(p!=NULL){printf("%s\t%d\t%d\t%d\t%d\t\t%c\t\t%d\n",p->name,p->prio,p->round,p->cputime,p->needtime, p->state,p->count);p = p->next;}}void InsertPrio(PCB *in) /*创建优先级队列,规定优先数越小,优先级越低*/{PCB *fst,*nxt;fst = nxt = ready;if(ready == NULL) /*如果队列为空,则为第一个元素*/{in->next = ready;ready = in;}else /*查到合适的位置进行插入*/{if(in ->prio > fst ->prio) /*比第一个还要大(大于等于),则插入到队头*/{in->next = ready;ready = in;}else{while(fst->next != NULL) /*移动指针查找第一个别它小的元素的位置进行插入*/{nxt = fst;fst = fst->next;}if(fst ->next == NULL) /*已经搜索到队尾,则其优先级数最小,将其插入到队尾即可*/{in ->next = fst ->next;fst ->next = in;}else /*插入到队列中*/{nxt = in;in ->next = fst;}}}}void InsertTime(PCB *in) /*将进程插入到就绪队列尾部*/ {PCB *fst;fst = ready;if(ready == NULL){in->next = ready;ready = in;}else{while(fst->next != NULL){fst = fst->next;}in ->next = fst ->next;fst ->next = in;}}void InsertFinish(PCB *in) /*将进程插入到完成队列尾部*/ {PCB *fst;fst = finish;if(finish == NULL){in->next = finish;finish = in;}else{while(fst->next != NULL){fst = fst->next;}in ->next = fst ->next;fst ->next = in;}}void PrioCreate() /*优先级调度输入函数*/{PCB *tmp;printf("输入进程名字和进程所需时间:\n");for(i = 0;i < num; i++){if((tmp = (PCB *)malloc(sizeof(PCB)))==NULL){perror("malloc");exit(1);}scanf("%s",tmp->name);getchar(); /*吸收回车符号*/scanf("%d",&(tmp->needtime));tmp ->cputime = 0;tmp ->state ='W';tmp ->prio = 50 - tmp->needtime; /*设置其优先级,需要的时间越多,优先级越低*/tmp ->round = 0;tmp ->count = 0;InsertPrio(tmp); /*按照优先级从高到低,插入到就绪队列*/}}void TimeCreate() /*时间片输入函数*/{PCB *tmp;int i;printf("输入进程名字和进程时间片所需时间:\n");for(i = 0;i < num; i++){if((tmp = (PCB *)malloc(sizeof(PCB)))==NULL){perror("malloc");exit(1);}scanf("%s",tmp->name);getchar();scanf("%d",&(tmp->needtime));tmp ->cputime = 0;tmp ->state ='W';tmp ->prio = 0;tmp ->round = 2; /*假设每个进程所分配的时间片是2*/tmp ->count = 0;InsertTime(tmp);}void Priority() /*按照优先级调度,每次执行一个时间片*/{int flag = 1;GetFirst();while(run != NULL) /*当就绪队列不为空时,则调度进程如执行队列执行*/{Output(); /*输出每次调度过程中各个节点的状态*/while(flag){run->prio -= 0; /*优先级减去三,若设为0则优先级不变*/run->cputime++; /*CPU时间片加一*/run->needtime--;/*进程执行完成的剩余时间减一*/if(run->needtime == 0)/*如果进程执行完毕,将进程状态置为F,将其插入到完成队列*/{run ->state = 'F';run->count++; /*进程执行的次数加一*/InsertFinish(run);flag = 0;}else /*将进程状态置为W,入就绪队列*/{run->state = 'W';run->count++; /*进程执行的次数加一*/InsertTime(run);flag = 0;}}flag = 1;GetFirst(); /*继续取就绪队列队头进程进入执行队列*/}}void RoundRun() /*时间片轮转调度算法*/{int flag = 1;GetFirst();while(run != NULL){Output();while(flag){run->count++;run->cputime++;run->needtime--;if(run->needtime == 0) /*进程执行完毕*/{run ->state = 'F';InsertFinish(run);flag = 0;}else if(run->count == run->round)/*时间片用完*/{run->state = 'W';run->count = 0; /*计数器清零,为下次做准备*/InsertTime(run);flag = 0;}}flag = 1;GetFirst();}}4、运行结果以及结论。
操作系统上实验报告3汇总
![操作系统上实验报告3汇总](https://img.taocdn.com/s3/m/39fc709a8762caaedd33d494.png)
操作系统实验三报告实验题目:进程管理及进程通信实验环境:虚拟机Linux操作系统实验目的:1.利用Linux提供的系统调用设计程序,加深对进程概念的理解。
2.体会系统进程调度的方法和效果。
3.了解进程之间的通信方式以及各种通信方式的使用。
实验内容:例程1:利用fork()创建子进程#include<stdio.h>#include<stdlib.h>#include<unistd.h>main(){int i;if (fork())i=wait(0);/*父进程执行的程序段*//* 等待子进程结束*/printf("It is parent process.\n");printf("The child process,ID number %d, is finished.\n",i);}else{printf("It is child process.\n");sleep(10);/*子进程执行的程序段*/exit(1);/*向父进程发出结束信号*/}}运行结果:思考:子进程是如何产生的?又是如何结束的?子进程被创建后它的运行环境是怎样建立的?答:子进程是通过函数fork()创建的,通过exit()函数自我结束的,子进程被创建后核心将为其分配一个进程表项和进程标识符,检查同时运行的进程数目,并且拷贝进程表项的数据,由子进程继承父进程的所有文件。
例程2:循环调用fork()创建多个子进程#include<stdio.h>#include<stdlib.h>#include<unistd.h>main(){ int i,j;printf(“My pid is %d, my father’s pid is %d\n”,getpid(),getppid());for(i=0; i<3; i++)if(fork()==0)printf(“%d pid=%d ppid=%d\n”, i,getpid(),getppid());else{ j=wait(0);Printf(“ %d:The chile %d is finished.\n” ,getpid(),j);}}运行结果:思考:画出进程的家族树。
操作系统实验三
![操作系统实验三](https://img.taocdn.com/s3/m/e504a919f68a6529647d27284b73f242326c3143.png)
操作系统实验三操作系统实验报告哈尔滨⼯程⼤学计算机科学与技术学院第三讲进程的创建⼀、实验概述1. 实验名称进程的创建2. 实验⽬的练习使⽤EOS API函数CreateProcess创建⼀个进程,掌握创建进程的⽅法,理解进程和程序的区别。
调试跟踪CreateProcess函数的执⾏过程,了解进程的创建过程,理解进程是资源分配的单位。
3. 实验类型设计4. 实验内容准备实验按照下⾯的步骤准备本次实验:1. 启动OS Lab。
2. 新建⼀个EOS Kernel项⽬。
3. 分别使⽤Debug配置和Release配置⽣成此项⽬,从⽽在该项⽬⽂件夹中⽣成完全版本的EOS SDK⽂件夹。
4. 新建⼀个EOS应⽤程序项⽬。
5. 使⽤在第3步⽣成的SDK⽂件夹覆盖EOS应⽤程序项⽬⽂件夹中的SDK⽂件夹。
练习使⽤控制台命令创建EOS应⽤程序的进程练习使⽤控制台命令创建EOS应⽤程序进程的具体步骤如下:1. 在EOS应⽤程序项⽬的“项⽬管理器”窗⼝中双击⽂件,使⽤FloppyImageEditor⼯具打开此软盘镜像⽂件。
2. 将本实验⽂件夹中的⽂件拖动到FloppyImageEditor⼯具窗⼝的⽂件列表中释放,⽂件即被添加到软盘镜像⽂件中。
⼀个EOS应⽤程序,其源代码可以参见本实验⽂件夹中的源⽂件。
3. 在FloppyImageEditor中选择“⽂件”菜单中的“保存”后关闭FloppyImageEditor。
4. 按F7⽣成EOS应⽤项⽬。
5. 按F5启动调试。
OS Lab会弹出⼀个调试异常对话框,并中断应⽤程序的执⾏。
6. 在调试异常对话框中选择“否”,忽略异常继续执⾏应⽤程序。
7. 激活虚拟机窗⼝,待该应⽤程序执⾏完毕后,在EOS的控制台中输⼊命令“A:\”后回车。
8. 应⽤程序开始执⾏,观察其输出。
9. 待执⾏完毕后可以重复第7步,或者结束此次调试。
练习通过编程的⽅式让应⽤程序创建另⼀个应⽤程序的进程使⽤OS Lab打开本实验⽂件夹中的⽂件(将此⽂件拖动到OS Lab窗⼝中释放即可),仔细阅读此⽂件中的源代码和注释。
操作系统实验三
![操作系统实验三](https://img.taocdn.com/s3/m/6ecfed52591b6bd97f192279168884868762b8d1.png)
操作系统实验三在学习操作系统的过程中,实验是帮助我们深入理解其原理和机制的重要手段。
这次的操作系统实验三,让我对操作系统的某些关键概念和功能有了更直观的认识和更深刻的体会。
本次实验的主要目标是深入探究操作系统中的进程管理和调度机制。
进程作为操作系统中最基本的概念之一,它的管理和调度直接影响着系统的性能和资源利用率。
实验开始前,我们需要对相关的理论知识进行充分的复习和准备。
了解进程的状态转换、进程控制块的结构和作用、各种进程调度算法的原理等等,这些知识为我们后续的实验操作打下了坚实的基础。
在实验过程中,我们首先通过编程实现了对进程的创建、撤销、阻塞和唤醒等基本操作。
这让我清晰地看到了进程从产生到消亡的整个生命周期,以及在不同状态之间的转换过程。
通过观察和分析进程状态的变化,我更加深入地理解了操作系统是如何有效地管理和控制进程的运行。
接下来,我们重点研究了进程调度算法。
常见的进程调度算法有先来先服务(FCFS)、短作业优先(SJF)、时间片轮转(RR)等。
我们通过编写代码,模拟了不同调度算法下进程的执行情况,并对其性能进行了评估和比较。
先来先服务算法按照进程到达的先后顺序进行调度,这种算法实现简单,但可能导致短作业等待时间过长,从而影响系统的整体性能。
短作业优先算法则优先调度执行时间短的作业,能够有效地减少平均等待时间,但可能会对长作业不利,导致长作业长时间得不到执行。
时间片轮转算法则将 CPU 的时间划分成固定大小的时间片,每个进程轮流使用一个时间片,这种算法能够保证每个进程都能得到一定的CPU 时间,但如果时间片设置不当,可能会导致频繁的进程切换,增加系统开销。
通过对这些调度算法的模拟和分析,我不仅学会了如何在代码中实现它们,更重要的是理解了它们的优缺点以及适用场景。
这让我明白,在实际的操作系统中,选择合适的调度算法需要综合考虑多种因素,如系统的负载情况、进程的特性、用户的需求等等。
在实验中,我们还遇到了一些问题和挑战。
操作系统实验报告3
![操作系统实验报告3](https://img.taocdn.com/s3/m/26b17ae90d22590102020740be1e650e52eacf8d.png)
日期:2022-5-25实习题目:完成人姓名:1. 实验内容:组号:一学号:实习内容简要描述主要代码结构( 附注释)结果分析 ( 或者错误原因分析)要求实现用户空间内的作业调度系统,通过作业调度系统实现以下的操作:(1)提交自己的作业。
(2)将自己提交的作业移出。
(3)查看做业状态。
2.实验目的:(1).理解操作系统中调度的概念和调度算法。
(2).学习Linux 下进程控制以及进程之间通信的知识。
(3).理解在操作系统中作业是如何被调度的,如何协调和控制各作业对CPU 的使用。
3.实验环境:windows 2000/xp ,Linux 系统虚拟机见附表(一)一.实验方法要完成实验作业调度系统,还需要编写实验代码。
在linux系统终端中,写一个可以执行的作业。
下面将一个作业的代码写出来。
注释:如果上述表格空间不够,可以另附表格进行说明结果分析(或者错误原将让面的程序保存为p1.c。
接下来就在linux系统终端中进行处理。
1. 打开一终端,编译 scheduler.c ,stat.c ,enq.c,deq.c 文件。
2. 自己定义 5 个程序,为 p1,p2,p3,p4,p5,这 5 个程序运行时间满足大于 100 毫秒,编译这个 5 个程序。
因分析) 3. 当上面的工作完成后,在一个终端”A”里面运行”./scheduler”程序,然后再开一个终端”B”,运行“./enq p1 ”,同理,运行 p2,p3,p4,p5, 也可以运行 stat jid 和 deq jid 命令,在 A 终端里面观察相对应的变化。
结果如下终端 B终端 A二.结果分析1.当在 A 终端中运行 scheduler 程序后,结果如下表明 Scheduler 程序已经运行。
2. 在 B 终端中运行./enq p1。
在 A 终端中浮现如下的结果:表明新的 job 已经建立。
Jid 为 1,pid 为 16914.3. 在 B 终端中运行./stat 。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验三操作系统进程调度算法一、实验目的和要求:目的:对操作系统中使用的进程调度算法进行改进性设计。
要求:对教材中所讲述的几种进程调度算法进行深入的分析,然后选取其中的一种算法进行改进,并编程实现此算法。
二、实验内容:1、设计进程控制块PCB表结构,分别适用于优先数调度算法和先来先服务调度算法。
2、建立进程就绪队列。
对两种不同算法编制入链子程序。
3、编制两种进程调度算法:1)优先数调度;2)先来先服务三、实验原理:先来先服务调度算法:按进程进入就绪队列的先后次序选择可以占用处理器的进程。
优先级调度算法:对每个进程确定一个优先数,该算法总是让优先数最高的进程先使用处理器。
对具有相同优先数的进程,再采用先来先服务的次序分配处理器。
系统常以任务的紧迫性和系统效率等因素确定进程的优先数。
进程的优先数可以固定的,也可随进程执行过程动态变化。
一个高优先数的进程占用处理器后,系统处理该进程时有两种方法,一是"非抢占式",另一种是"可抢占式"。
前者是此进程占用处理器后一直运行到结束,除非本身主动让出处理器,后者则是严格保证任何时刻总是让优先数最高的进程在处理器上运行(本实验采用“可抢占式”)。
四、实验提示:1、用两种算法对多个进程进行调度,每个进程可有三个状态,并假设初始状态为就绪状态。
2、为了便于处理,程序中的某进程运行时间以时间片为单位计算。
各进程的优先数及进程需运行的时间片数的初始值均由用户给定。
3、在优先数算法中,优先数可以先取值为n,进程每执行一次,优先数减3,进程还需要的cpu时间片数减1。
在先来先服务算法中,采用固定时间片(即:每执行一次进程,该进程的执行时间片数为已执行了2个单位),这时进程还需要的时间片数减2,并排列到就绪队列的尾上。
4、对于遇到优先数一致的情况,采用FIFO策略解决。
5、流程图五、实验结论FCFS算法:void FCFS(){intstartWorkTime = 0;int first = get_firstProcess();isFinished_FCFS[first] = true;FinishTime[first] = ArrivalTime[first] + ServiceTime[first];startWorkTime += ServiceTime[first];WholeTime[first] = FinishTime[first] - ArrivalTime[first];WeightWholeTime[first] = WholeTime[first]/ServiceTime[first];intnextProcess = n;for (inti=1;i<n;i++){nextProcess = n;for (int j=0;j<n;j++){if (!isFinished_FCFS[j]){if (ArrivalTime[j]<=startWorkTime){if (nextProcess==n){nextProcess = j;}else{if (ArrivalTime[nextProcess]>ArrivalTime[j]){nextProcess=j;}}}}}isFinished_FCFS[nextProcess] = true;FinishTime[nextProcess] = ServiceTime[nextProcess] + startWorkTime;startWorkTime += ServiceTime[nextProcess];WholeTime[nextProcess] = FinishTime[nextProcess] - ArrivalTime[nextProcess];WeightWholeTime[nextProcess] =(double)WholeTime[nextProcess]/ServiceTime[nextProcess];}doubletotalWT = 0;doubletotalWWT = 0;for (inti=0;i<n;i++){totalWT+=WholeTime[i];totalWWT+=WeightWholeTime[i];}AverageWT_FCFS = totalWT/n;AverageWWT_FCFS = totalWWT/n;display();cout<<"平均周转时间="<<AverageWT_FCFS<<endl;cout<<"平均带权周转时间="<<AverageWWT_FCFS<<endl;cout<<"******************************************************"<<endl; }SJF算法:void SJF(){intstartWorkTime_SJF = 0;int first = get_firstProcess();isFinished_SJF[first] = true;FinishTime[first] = ArrivalTime[first] + ServiceTime[first];startWorkTime_SJF += ServiceTime[first];WholeTime[first] = FinishTime[first] - ArrivalTime[first];WeightWholeTime[first] = (double)WholeTime[first]/ServiceTime[first];intnextProcess_SJF = n;for (inti=1;i<n;i++){nextProcess_SJF = n;for (int j=0;j<n;j++){if (!isFinished_SJF[j]){if (ArrivalTime[j]<=startWorkTime_SJF){if (nextProcess_SJF==n){nextProcess_SJF = j;}else{if (ServiceTime[nextProcess_SJF]>ServiceTime[j]){nextProcess_SJF = j;}}}}}//for(j)isFinished_SJF[nextProcess_SJF] = true;FinishTime[nextProcess_SJF] = ServiceTime[nextProcess_SJF] + startWorkTime_SJF;startWorkTime_SJF += ServiceTime[nextProcess_SJF];WholeTime[nextProcess_SJF] = FinishTime[nextProcess_SJF] - ArrivalTime[nextProcess_SJF];WeightWholeTime[nextProcess_SJF] = (double)WholeTime[nextProcess_SJF]/ServiceTime[nextProcess_SJF];}//for(i)doubletotalWT = 0;doubletotalWWT = 0;for (inti=0;i<n;i++){totalWT+=WholeTime[i];totalWWT+=WeightWholeTime[i];}AverageWT_SJF = totalWT/n;AverageWWT_SJF = totalWWT/n;display();cout<<"平均周转时间="<<AverageWT_SJF<<endl;cout<<"平均带权周转时间="<<AverageWWT_SJF<<endl;cout<<"******************************************************"<<endl;}六、实验过程中所遇问题思考与讨论通过此次实验模拟了FCFS和FJS算法先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。
当在作业调度中采用该算法时,每次调度都是从后备作业队列中选择一个或多个最先进入该队列的作业,将它们调入内存,为它们分配资源、创建进程,然后放入就绪队列。
在进程调度中采用FCFS算法时,则每次调度是从就绪队列中选择一个最先进入该队列的进程,为之分配处理机,使之投入运行。
该进程一直运行到完成或发生某事件而阻塞后才放弃处理机。
SJF调度算法也存在不容忽视的缺点:该算法对长作业不利,如作业C的周转时间由10增至16,其带权周转时间由2增至3.1。
更严重的是,如果有一长作业(进程)进入系统的后备队列(就绪队列),由于调度程序总是优先调度那些(即使是后进来的)短作业(进程),将导致长作业(进程)长期不被调度。
该算法完全未考虑作业的紧迫程度,因而不能保证紧迫性作业(进程)会被及时处理。
由于作业(进程)的长短只是根据用户所提供的估计执行时间而定的,而用户又可能会有意或无意地缩短其作业的估计运行时间,致使该算法不一定能真正做到短作业优先调度。
通过此次实验,获益匪浅。