实验2 进程状态转换及其PCB的变化
操作系统实验二:进程管理
操作系统实验二:进程管理操作系统实验二:进程管理篇一:操作系统实验报告实验一进程管理一、目的进程调度是处理机管理的核心内容。
本实验要求编写和调试一个简单的进程调度程序。
通过本实验加深理解有关进程控制块、进程队列的概念,并体会和了解进程调度算法的具体实施办法。
二、实验内容及要求1、设计进程控制块PCB的结构(PCB结构通常包括以下信息:进程名(进程ID)、进程优先数、轮转时间片、进程所占用的CPU时间、进程的状态、当前队列指针等。
可根据实验的不同,PCB结构的内容可以作适当的增删)。
为了便于处理,程序中的某进程运行时间以时间片为单位计算。
各进程的轮转时间数以及进程需运行的时间片数的初始值均由用户给定。
2、系统资源(r1…rw),共有w类,每类数目为r1…rw。
随机产生n进程Pi(id,s(j,k)t),0<=i<=n,0<=j<=m,0<=k<=dt为总运行时间,在运行过程中,会随机申请新的资源。
3、每个进程可有三个状态(即就绪状态W、运行状态R、等待或阻塞状态B),并假设初始状态为就绪状态。
建立进程就绪队列。
4、编制进程调度算法:时间片轮转调度算法本程序用该算法对n个进程进行调度,进程每执行一次,CPU时间片数加1,进程还需要的时间片数减1。
在调度算法中,采用固定时间片(即:每执行一次进程,该进程的执行时间片数为已执行了1个单位),这时,CPU时间片数加1,进程还需要的时间片数减1,并排列到就绪队列的尾上。
三、实验环境操作系统环境:Windows系统。
编程语言:C#。
四、实验思路和设计1、程序流程图2、主要程序代码//PCB结构体struct pcb{public int id; //进程IDpublic int ra; //所需资源A的数量public int rb; //所需资源B的数量public int rc; //所需资源C的数量public int ntime; //所需的时间片个数public int rtime; //已经运行的时间片个数public char state; //进程状态,W(等待)、R(运行)、B(阻塞)//public int next;}ArrayList hready = new ArrayList();ArrayList hblock = new ArrayList();Random random = new Random();//ArrayList p = new ArrayList();int m, n, r, a,a1, b,b1, c,c1, h = 0, i = 1, time1Inteval;//m为要模拟的进程个数,n为初始化进程个数//r为可随机产生的进程数(r=m-n)//a,b,c分别为A,B,C三类资源的总量//i为进城计数,i=1…n//h为运行的时间片次数,time1Inteval为时间片大小(毫秒)//对进程进行初始化,建立就绪数组、阻塞数组。
2.2 进程的状态及转换
2.2 进程的状态及转换进程是操作系统中的基本执行单元,它的状态及其转换对于系统的正常运行具有重要的意义。
在本文中,我们将讨论进程的状态及各种状态之间的转换,以便更好地理解进程的运行机制。
进程的状态一般分为五种:(1)创建态(new):当进程被创建但还未被执行时,它处于创建态。
此时,操作系统会为进程分配必要的资源,比如代码段、数据段、堆栈等,以便其能够执行。
(2)就绪态(ready):当进程已经准备好执行时,但由于当前处理机正忙于执行其他进程,导致该进程无法执行时,它处于就绪态。
此时进程已经将所有必要的资源准备好,只需要分配到CPU才能运行。
(3)运行态(running):当进程获得处理器时间并开始执行指令时,它处于运行态。
此时,进程会按照指令进行操作。
(4)阻塞态(blocked):当进程由于某些原因无法继续执行时,它进入阻塞态。
比如,进程需要等待某个资源(如读取磁盘数据),或者它正在等待输入输出操作的结果。
(5)终止态(terminated):当进程执行完毕或被强制终止时,它进入终止态。
此时,操作系统会释放进程所持有的资源,以便其他进程使用。
进程的状态之间可以相互转换。
在操作系统中,许多事件都可能导致进程状态的转换,比如中断请求、操作系统的调度、进程自身的请求等等。
下面我们来看几个具体的转换:(1)创建态-->就绪态:当操作系统为进程分配到必要的资源之后,进程会从创建态转换到就绪态。
此时进程已经准备好执行,只是没有获取到CPU的时间片。
(3)运行态-->就绪态:当进程执行完毕所有指令并主动释放CPU时间片时,它会从运行态转换到就绪态,等待下一次操作系统调度。
(4)运行态-->阻塞态:当进程需要等待某个事件发生时,它会从运行态转换到阻塞态。
比如,读取磁盘数据时就需要等待磁盘完成读取操作。
(5)阻塞态-->就绪态:当进程等待的事件已经发生或操作系统主动为其分配资源时,它会从阻塞态返回到就绪态,等待下一次操作系统调度。
操作系统进程的三种状态的转换实验报告
3.设计出可视性较好的界面,应能反映出进程状态的变化引起的对应内容。
4.代码书写要规范,要适当地加入注释。
5.编译并调试自己编写的程序,是程序编译成功。
6.检查运行的结果是否正确。
四、实验结果(含算法说明、程序、数据记录及分析等,可附页)
五、实验思考题
利用C语言编写了一个模拟Windows进程三种状态之间的转换的程序,虽然肥城精简,但是我从中学到的很多知识点,学会了编写程序时的一些技巧,为自己以后更加深造打下了坚实的基础和使自己更好的理解Windows如何更好的管理进程。
六、实验总结(含实验心得体会,收获与不足等)
通过这次实验让我受益匪浅,不仅明白了自己以前不知道如何定义和应用结构体,还提高了自己的编程能力,调试程序的能力,使自己的编程能力有了大幅度的提高。使自己更好的理解进程的概念和进程的三种状态之间转换的过程和他们之间的关系。为自己以后复习打下了夯实的基础。
1)根据课本第三章的内容设计并实现一个模拟进程状态转换。
2)独立编写和调试程序。进程的数目,进程的状态模型自行选择。
3)合理设计进程相对应的数据结构,内容要包括进程的基本信息。
4)是进程的三种状态之间的转化清晰的显示。
三、实验过程及步骤(包含使用软件或实验设备等情况)
1.打开DEV-C++,新建一个源代码文件
实验报告
实验名称
进程三种状态的转换
专业
计算机
课程名称
操作系统
指导老师
张海燕
班级
二表一班
姓名
刘广法
学号
11100140109
评分
实验地点
1cபைடு நூலகம்6217
实验二 进程调度实验
实验二进程调度实验(2学时)一、实验目的用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
二、实验内容:任务:设计一个有N个进程并行的进程调度程序进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和同优先级条件下先来先服务算法。
每个进程有一个进程控制块(PCB)表示。
进程控制块可以包含如下信息:进程名、优先数、需要运行时间、已用CPU时间、进程状态等等。
进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。
进程的运行时间以时间片为单位进行计算。
每个进程的状态可以是就绪W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。
就绪进程获得CPU后都只能运行一个时间片。
用已占用CPU时间加1来表示。
如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。
每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。
重复以上过程,直到所要进程都完成为止。
调度算法的流程图2如下:图2调度算法的流程图三、实验步骤(1) 打开VC,选择菜单项file->new,选择projects选项卡并建立一个名为" ry2"的win32 console applicatoin工程;创建时注意指定创建该工程的目录;(2) 在工程中创建源文件" ry2.cpp":选择菜单项project->add to project->files,在选择框中输入自己想要创建的文件名,这里是" ry2.cpp";在接下来询问是否创建新文件时回答"yes";然后通过Workspace->FileView->Source Files打开该文件,在其中编辑源文件并保存.(3) 通过调用菜单命令项build->build all进行编译连接,可以在指定的工程目录下得到debug-> sy2.exe程序,运行sy2.exe。
进程的调度实验报告(3篇)
第1篇一、实验目的通过本次实验,加深对操作系统进程调度原理的理解,掌握先来先服务(FCFS)、时间片轮转(RR)和动态优先级(DP)三种常见调度算法的实现,并能够分析这些算法的优缺点,提高程序设计能力。
二、实验环境- 编程语言:C语言- 操作系统:Linux- 编译器:GCC三、实验内容本实验主要实现以下内容:1. 定义进程控制块(PCB)结构体,包含进程名、到达时间、服务时间、优先级、状态等信息。
2. 实现三种调度算法:FCFS、RR和DP。
3. 创建一个进程队列,用于存储所有进程。
4. 实现调度函数,根据所选算法选择下一个执行的进程。
5. 模拟进程执行过程,打印进程执行状态和就绪队列。
四、实验步骤1. 定义PCB结构体:```ctypedef struct PCB {char processName[10];int arrivalTime;int serviceTime;int priority;int usedTime;int state; // 0: 等待,1: 运行,2: 完成} PCB;```2. 创建进程队列:```cPCB processes[MAX_PROCESSES]; // 假设最多有MAX_PROCESSES个进程int processCount = 0; // 实际进程数量```3. 实现三种调度算法:(1)FCFS调度算法:```cvoid fcfsScheduling() {int i, j;for (i = 0; i < processCount; i++) {processes[i].state = 1; // 设置为运行状态printf("正在运行进程:%s\n", processes[i].processName); processes[i].usedTime++;if (processes[i].usedTime == processes[i].serviceTime) { processes[i].state = 2; // 设置为完成状态printf("进程:%s 完成\n", processes[i].processName); }for (j = i + 1; j < processCount; j++) {processes[j].arrivalTime--;}}}```(2)RR调度算法:```cvoid rrScheduling() {int i, j, quantum = 1; // 时间片for (i = 0; i < processCount; i++) {processes[i].state = 1; // 设置为运行状态printf("正在运行进程:%s\n", processes[i].processName); processes[i].usedTime++;processes[i].serviceTime--;if (processes[i].serviceTime <= 0) {processes[i].state = 2; // 设置为完成状态printf("进程:%s 完成\n", processes[i].processName); } else {processes[i].arrivalTime++;}for (j = i + 1; j < processCount; j++) {processes[j].arrivalTime--;}}}```(3)DP调度算法:```cvoid dpScheduling() {int i, j, minPriority = MAX_PRIORITY;int minIndex = -1;for (i = 0; i < processCount; i++) {if (processes[i].arrivalTime <= 0 && processes[i].priority < minPriority) {minPriority = processes[i].priority;minIndex = i;}}if (minIndex != -1) {processes[minIndex].state = 1; // 设置为运行状态printf("正在运行进程:%s\n", processes[minIndex].processName);processes[minIndex].usedTime++;processes[minIndex].priority--;processes[minIndex].serviceTime--;if (processes[minIndex].serviceTime <= 0) {processes[minIndex].state = 2; // 设置为完成状态printf("进程:%s 完成\n", processes[minIndex].processName); }}}```4. 模拟进程执行过程:```cvoid simulateProcess() {printf("请选择调度算法(1:FCFS,2:RR,3:DP):");int choice;scanf("%d", &choice);switch (choice) {case 1:fcfsScheduling();break;case 2:rrScheduling();break;case 3:dpScheduling();break;default:printf("无效的调度算法选择。
进程操作的实验报告
一、实验目的1. 理解进程的基本概念和进程控制块(PCB)的作用。
2. 掌握进程创建、调度、同步和通信的基本方法。
3. 熟悉进程状态转换及进程同步机制。
4. 提高编程能力,加深对操作系统进程管理的理解。
二、实验环境1. 操作系统:Windows 102. 编程语言:C/C++3. 开发环境:Visual Studio 2019三、实验内容1. 进程创建与销毁2. 进程调度3. 进程同步4. 进程通信四、实验步骤1. 进程创建与销毁(1)定义进程结构体```ctypedef struct {int pid; // 进程IDchar name[50]; // 进程名int status; // 进程状态struct PCB next; // 指向下一个进程的指针} PCB;```(2)创建进程```cPCB createProcess(char name) {PCB newProcess = (PCB )malloc(sizeof(PCB)); newProcess->pid = ...; // 分配进程IDstrcpy(newProcess->name, name);newProcess->status = ...; // 初始化进程状态 newProcess->next = NULL;// ... 其他初始化操作return newProcess;}```(3)销毁进程```cvoid destroyProcess(PCB process) {free(process);}```2. 进程调度(1)定义进程队列```ctypedef struct {PCB head; // 队列头指针PCB tail; // 队列尾指针} ProcessQueue;```(2)初始化进程队列```cvoid initProcessQueue(ProcessQueue queue) {queue->head = NULL;queue->tail = NULL;}```(3)入队```cvoid enqueue(ProcessQueue queue, PCB process) { if (queue->head == NULL) {queue->head = process;queue->tail = process;} else {queue->tail->next = process;queue->tail = process;}}(4)出队```cPCB dequeue(ProcessQueue queue) {if (queue->head == NULL) {return NULL;}PCB process = queue->head;queue->head = queue->head->next; if (queue->head == NULL) {queue->tail = NULL;}return process;}```3. 进程同步(1)互斥锁```ctypedef struct {int locked; // 锁的状态} Mutex;void initMutex(Mutex mutex) {mutex->locked = 0;void lock(Mutex mutex) {while (mutex->locked) {// 等待锁释放}mutex->locked = 1;}void unlock(Mutex mutex) {mutex->locked = 0;}```(2)信号量```ctypedef struct {int count; // 信号量值Mutex mutex; // 互斥锁} Semaphore;void initSemaphore(Semaphore semaphore, int count) { semaphore->count = count;initMutex(&semaphore->mutex);}void P(Semaphore semaphore) {lock(&semaphore->mutex);while (semaphore->count <= 0) {// 等待信号量}semaphore->count--;unlock(&semaphore->mutex);}void V(Semaphore semaphore) {lock(&semaphore->mutex);semaphore->count++;unlock(&semaphore->mutex);}```4. 进程通信(1)管道通信```cint pipe(int pipefd[2]) {// 创建管道}void writePipe(int pipefd[2], const void buf, size_t nbyte) { // 向管道写入数据}void readPipe(int pipefd[2], void buf, size_t nbyte) {// 从管道读取数据}```(2)消息队列通信```cint msgget(key_t key, int msgflg) {// 创建消息队列}void msgsnd(int msqid, const void msgp, size_t msgsz, int msgflg) {// 向消息队列发送消息}void msgrcv(int msqid, void msgp, size_t msgsz, long msgtype, int msgflg) {// 从消息队列接收消息}```五、实验结果与分析1. 进程创建与销毁:通过创建和销毁进程,验证了进程结构体的正确性。
PCB[进程控制块作用]
PCB为了描述控制进程的运行,系统中存放进程的管理和控制信息的数据结构称为进程控制块(PCB Process Control Block),它是进程实体的一部分,是操作系统中最重要的记录性数据结构。
它是进程管理和控制的最重要的数据结构,每一个进程均有一个PCB,在创建进程时,建立PCB,伴随进程运行的全过程,直到进程撤消而撤消。
中文名进程管理块外文名Process Control BlockPCB中记录了操作系统所需的,用于描述进程的当前情况以及控制进程运行的全部信息。
PCB 的作用是使一个在多道程序环境下不能独立运行的程序(含数据),成为一个能独立运行的基本单位,一个能与其他进程并发执行的进程。
或者说,OS是根据PCB来对并发执行的进程进行控制和管理的。
例如,当OS要调度某进程执行时,要从该进程的PCB中查处其现行状态及优先级;在调度到某进程后,要根据其PCB中所保存的处理机状态信息,设置该进程恢复运行的现场,并根据其PCB中的程序和数据的内存始址,找到其程序和数据;进程在执行过程中,当需要和与之合作的进程实现同步,通信或者访问文件时,也都需要访问PCB;当进程由于某种原因而暂停执行时,又须将器断点的处理机环境保存在PCB中。
可见,在进程的整个生命期中,系统总是通过PCB对进程进行控制的,即系统是根据进程的PCB 而不是任何别的什么而感知到该进程的存在的。
所以说,PCB是进程存在的唯一标志。
组成PCB进程控制块是进程的静态描述,由PCB、有关程序段和该程序段对其进行操作的数据结构集三部分组成。
在Unix或类Unix系统中,进程是由进程控制块,进程执行的程序,进程执行时所用数据,进程运行使用的工作区组成。
其中进程控制块是最重要的一部分。
进程控制块是用来描述进程的当前状态,本身特性的数据结构,是进程中组成的最关键部分,其中含有描述进程信息和控制信息,是进程的集中特性反映,是操作系统对进程具体进行识别和控制的依据。
操作系统作业《模拟进程转换》
实验一进程状态模拟进程状态转换及其PCB的变化一.实验目的自行编制模拟程序,通过形象化的状态显示,使学生理解进程的概念、进程之间的状态转换及其所带来的PCB内容、组织的变化,理解进程与其PCB间的一一对应关系。
二. 实验要求设计并实现一个模拟进程状态转换及其相应PCB组织结构变化的程序;独立设计、编写、调试程序;程序界面应能反映出在模拟条件下,进程之间状态转换及其对应的PCB组织的变化。
三. 程序流程图时间片超时初始化进程状态接收用户操作命令S时间等待进程调度 开始S=1? S=2?S=3?事件发生显示PCB 信息结束退出?四. 数据结构本次试验主要用到的是队列的数据结构: 就绪队列:queue Q0;等待队列: queue Q1;五.源程序#include<iostream>#include<stdlib.h>#include<queue>using namespace std;queue <char>q[11];void menu();char ch; //CPU中运行的进程void Qout(int a) //输出队列中的进程{char c;switch(a){case 0: cout<<"就绪队列:";break;case 1: cout<<"等待队列:";break;case 2: cout<<"就绪队列:";break;case 3: cout<<"等待队列:";break;case 4: cout<<"就绪队列:";break;case 5: cout<<"等待队列:";break;case 6: cout<<"就绪队列:";break;case 7: cout<<"等待队列:";break;case 8: cout<<"就绪队列:";break;case 9: cout<<"等待队列:";break;case 10: cout<<"就绪队列:";break;case 11: cout<<"等待队列:";break;default:break;}while(!q[a].empty()){c=q[a].front();cout<<c<<" ";q[a].pop();}cout<<endl;}void Dispatch(){if(q[0].empty())cout<<"就绪队列为空,无法调度!"<<endl;else{ch=q[0].front();q[0].pop();q[2]=q[0];q[3]=q[1];Qout(2);Qout(3);cout<<"运行:"<<ch<<endl;}menu();}void Timeout(){if(ch>='A'&&ch<='E') //判断CPU不为空{q[0].push(ch);ch=q[0].front();q[0].pop();q[4]=q[0];q[5]=q[1];Qout(4);Qout(5);cout<<"运行:"<<ch<<endl;}else cout<<"CPU空闲,不存在超时!"<<endl;menu();}void Event_Wait(){if(ch>='A'&&ch<='E'&&!q[0].empty()){q[1].push(ch);ch=q[0].front();q[0].pop();q[8]=q[0];q[9]=q[1];Qout(8);Qout(9);cout<<"运行:"<<ch<<endl;}else {cout<<"CPU空闲或就绪队列为空!"<<endl;if(ch>='A'&&ch<='E'){q[1].push(ch);ch=' ';q[10]=q[0];q[11]=q[1];Qout(10);Qout(11);cout<<"运行:"<<ch<<endl;}}menu();}void Event_Occor(){ch=' ';if(!q[1].empty()){char c2=q[1].front();q[0].push(c2);q[1].pop();if(ch>='A'&&ch<='E'){q[6]=q[0];q[7]=q[1];Qout(6);Qout(7);cout<<"运行:"<<ch<<endl;}else{ch=q[0].front();q[0].pop();q[6]=q[0];q[7]=q[1];Qout(6);Qout(7);cout<<"运行:"<<ch<<endl;}}else cout<<"等待队列为空!"<<endl;menu();}void menu(){int s,m;cout<<"退出?(1:是;0:否) [ ]\b\b";cin>>m;while(1){if(m==1) exit(0);else if(m==0) break;else {cout<<"输入错误,请重新选择:[ ]\b\b";cin>>m;}}cout<<"请选择操作:[ ]\b\b";cin>>s;while(s!=1&&s!=2&&s!=3&&s!=4){cout<<"无此操作,请重新选择:[ ]\b\b";cin>>s;}switch(s){case 1: Dispatch();break;case 2: Timeout();break;case 3: Event_Wait();break;case 4: Event_Occor();break;default :break;}}int main(){char ch1='A';cout<<"操作说明:(1)Dispatch,(2)Timeout,(3)Event_Wait,(4)Event_Occor"<<endl;cout<<"我们预设初始状态如下"<<endl;cout<<"就绪队列:";for(int i=0;i<3;i++) //定义2个进程入就绪队列{cout<<ch1<<" ";q[0].push(ch1);ch1+=1;}cout<<endl;cout<<"等待队列:";for(int j=0;j<2;j++) //定义3个进程入等待队列{cout<<ch1<<" ";q[1].push(ch1);ch1+=1;}cout<<endl;cout<<"运行:"<<endl;menu();return 0;}六. 运行结果。
进程描述、状态转换和控制实验
计算机操作系统实验报告
PCB(){PID=-1;} }PCB,*PCBP; 5. 函数设计 5.1 用户选择菜单: 我们采用两级菜单显示: char menu()//用户选择菜单 char menu1()//进程操作菜单
0915257 吴龙龙
图 3-2 5.2 创建进程 void creat(int i,PCB a[]); 5.3 显示进程信息 void show(PCB a[]);
图 3-3 5.4 进程操作 1)io 请求 void iost(PCBP a,int i); 2)io 完成 void ioe(PCBP a,int i); 3)销毁进程 dest(PCBP a,int i);
2/6
计算机操作系统实验报告
0915257 吴龙龙
图 3-3 6. 数据测试 输入: 1\n2” ”3\n1\n3” ”4\n2\n3\n2\n1\n0\n2\n1\n4” ”5\n2\n\3\n2\n2\n0\n2 输出:
图 3-1 2.3 进程控制块 操作系统采用 PCB 块描述一个进程和其它进程以及系统资源的关系,刻 画一个进程在各个不同时期所处的状态. PCB 是系统感知进程存在的唯一标志, 进程与 PCB 是一一对应的. 3. 实验分析 根据实验要求,我们需要做的是模拟进程管理程序,其具体功能如下: 1) 进程创建 2) 进程显示 3) 对某进程操作: 1.io 请求 2.io 完成 3.销毁进程 4. 数据结构 typedef class PCB{ public: int PID; char name[10];//进程名 char state;//状态,R,W,G int pri;//priority 优先级 friend istream& operator >>(istream& ins,PCB& a);//重载>> friend ostream& operator <<(ostream& outs,PCB& a);//重载<<
实验二-----进程的同步
实验二:编程实现经典互斥和同步问题1.实验目的:加深对信号量、PV操作、进程同步和互斥等概念的理解,掌握PV操作的具体实现方法,熟练掌握进程同步和互斥的实现办法,能利用信号量机制解决实际生活中的同步和互斥问题。
2.实验内容(1)、编程实现P操作原语、V操作原语,(2)、用所定义的PV操作解决下面的问题:设学院某教室共有座位30个,任何时刻最多可容纳30名同学进入自习,当教室内人数少于30名时,则教室外等待的同学可立即进入,否则需在外面等待。
把一个欲进入教室自习的同学看作一个进程。
3、实验具体内容和步骤的说明(1)用户进程的定义(2)信号量的定义及初始化(3)PV操作的定义P操作顺序执行下述两个动作:①信号量的值减1,即S=S-1;②如果S≥0,则该进程继续执行(挂入就绪队列);如果S<0,则把该进程的状态置为阻塞态,把相应的PCB连入该信号量队列的末尾,并放弃处理机,进行等待(直至其它进程在S上执行V操作,把它释放出来为止)。
(挂入阻塞队列)V操作顺序执行下述两个动作:①S值加1,即S=S+1;②如果S>0,则该进程继续运行;(直接挂入就绪队列)如果S≤0,则释放信号量队列上的第一个PCB(即信号量指针项所指向的PCB)所对应的进程(把阻塞态改为就绪态),执行V操作的进程继续运行。
从阻塞队列唤醒一个进程,即从阻塞队列删除,挂入就绪队列(4)写出对应的主函数,解决多名同学之间的同步问题提示:设置2个进程队列,一是已经进入教室的,即就绪队列二是等待进入教室的,即阻塞队列程序:#include <stdio.h>#include <stdlib.h>typedef struct node{int name; //进程IDchar state;//进程状态struct node *next;}PCB;int s=3;//资源数PCB *stophead=NULL,*stoptail=NULL,*readyhead=NULL,*readytail=NULL;//阻塞就绪队列头尾指针void block(PCB *q)//无资源尾插入阻塞队列{q->state='B';if(stophead==NULL){stophead=q;stoptail=q;}else{stoptail->next=q;stoptail=q;}}void wakeup()//唤醒阻塞队列头节点尾插入就绪队列{stophead->state='R';if(readyhead==NULL){readyhead=stophead;readytail=stophead;stophead=stophead->next;readytail->next=NULL;}else{readytail->next=stophead;readytail=stophead;stophead=stophead->next;readytail->next=NULL;}}void p(PCB *q)//p操作{s=s-1;if(s<0)//无资源则插入阻塞队列block(q);else//尾插入就绪队列{q->state='R';if(readyhead==NULL){readyhead=q;readytail=q;}else{readytail->next=q;readytail=q;}}}int v(int b)//v操作{PCB *q,*pre;if(readyhead==NULL)//无就绪进程返回{printf(" 无就绪进程!\n\n");return 0;}pre=readyhead;q=readyhead;while(q->name!=b)//寻找就绪队列中v操作节点{if(q->next==NULL)//无当前查找节点{printf(" 查无此就绪进程!\n\n");return 1;}pre=q;q=q->next;//查找成功if(readyhead==readytail)//就绪队列仅有一个节点{readyhead=readytail=NULL;free(q);s=s+1;return 0;}else//就绪队列有多个节点{if(q==readyhead){readyhead=readyhead->next;free(q);//释放节点}else if(q==readytail){readytail=pre;pre->next=NULL;free(q);}else{pre->next=q->next;free(q);}s=s+1;if(s<=0)//如有阻塞进程则唤醒加入就绪队列wakeup();return 1;}}void show()//输出当前所有进程状态{PCB *q;q=readyhead;printf("\n");printf(" ID STATE\n");while(q!=NULL)printf("%5d%5c\n",q->name,q->state);q=q->next;}q=stophead;while(q!=NULL){printf("%5d%5c\n",q->name,q->state);q=q->next;}}void main(void){PCB *q;char a;int b;printf("\n剩余资源数%d ",s);printf("PLEASE INPUT:");scanf("%c %d",&a,&b);getchar();//输入当前操作类型进程ID (如p 1)while(a!='0')// (0 0)退出{if(a=='p')//执行p操作{q=(PCB *)malloc(sizeof(PCB));//进程初始化q->name=b;q->next=NULL;p(q);}else if(a=='v')//执行v操作b=v(b);if(b!=0)show();//显示当前进程状态printf("\n剩余资源数%d ",s);printf("PLEASE INPUT:");scanf("%c %d",&a,&b);getchar();}}。
操作系统实验2进程调度 实验报告
(2)掌握带优先级的进程调度算法;
(3)选用面向对象的编程方法。
二、实验内容;
(1)用C语言(或其它语言,如Java)实现对N个进程采用动态优先调度算法的调度。
(2)每个用来标识进程的进程控制块PCB可用结构来描述,包括以下字段:
进程标识数ID。
进程优先数PRIORITY,并规定优先数越大的进程,其优先权越高。
4.可动态添加、删除进程;
5.完成所有进程操作。
五、程序源代码及注释
六、实验结果分析
1、运行结果如下:
2、结果分析
首先,每次从就绪队列中选择最高优先权的进程时,需要计算出最高优先权和次高优先权之间的STARTBLOCK。即最高优先权进程运行多少个时间片后就会进入阻塞队列。每调度一次,就需要更新所有进程的信息,并判断CPUTIME是否等于ALLTIME,如果相等,则进程完成操作,需从就绪队列中删除。如果阻塞队列中进程的BLOCKTIME为0时,还需要将其转移到就绪队列中。
(5)用户可以干预进程的运行状态,程序应该设置可以让用户中断的入口,并可以通过以下命令查看,修改,终止进程。
A)create随机创建进程,进程的优先级与所需要的时间片随机决定;
B)ps查看当前进程状态
C)sleep命令将进程挂起
D)kill命令杀死进程
E)quit命令退出
(5)分析程序运行的结果,谈一下自己的认识。
三、实验原理;
无论是在批处理系统还是分时系统中,用户进程数一般都多于处理机数、这将导致它们互相争夺处理机。另外,系统进程也同样需要使用处理机。这就要求进程调度程序按一定的策略,动态地把处理机分配给处于就绪队列中的某一个进程,以使之执行。
根据进程的五个特征:(1)动态性;(2)并发性;(3)异步性;(4)独立性;(5)结构性及三种基本状态的转换,了解各进程对资源的共享和竞争。进程并发执行时,由于资源共享,带来各进程之间的相互制约。为了反映这些制约关系和资源共享关系,在创建一个进程时,应首先创建其PCB,然后才能根据PCB中信息对进程实施有效的管理和控制。当一个进程完成其功能之后,系统则最后释放PCB,进程也随之消亡。
实验二-实验报告(进程管理)
实验二模拟实现进程管理组长:李和林软件1402一、实验目的1.理解进程的概念,明确进程和程序的区别。
2.理解并发执行的实质。
3.掌握进程的创建,睡眠,撤销等进程控制方法。
二、实验内容用C语言,JAVA语言,C++语言编写程序,模拟实现创建新的进程;查看运行进程,换出某个进程;杀死运行进程。
三、实验准备1.进程的定义进程是程序在一个数据集合上的运行过程,是系统资源分配和调度的一个独立单位。
一个程序在不同的数据集合上运行,乃至一个程序在同样数据集合上的多次运行都是不同的进程。
2.进程的状态通常情况下,一个进程必须具有就绪,执行和阻塞三种基本情况。
1)就绪状态当进程已分配到除处理器外的所有必要资源后,只要再获得处理器就可以立即执行,这时进程的状态就为就绪状态。
在一个系统里,可以有多个进程同时处于就绪状态,通常把这些就绪进程排成一个或多个队列,称为就绪队列。
2)执行状态处于就绪状态的进程一旦获得处理器,就可以运行,进程状态也就处于执行状态,在单处理器系统中,只能有一个进程处于执行状态,在多处理器系统中,则可能有多个进程处于执行状态3)阻塞状态正在执行的进程因为发生某些事件而暂停运行,这种受阻暂停的状态称为阻塞状态,也可称为等待状态。
通常将处于阻塞状态的进程拍成一个队列,称为阻塞队列,在有些系统中,也会按阻塞原因的不同将阻塞状态的进程排成多个队列。
3.进程状态之间的转换4.进程控制块1)进程控制块的作用进程控制块是进程实体的重要组成部分,主要包含下述四个方面的信息:a)进程标示信息b)说明信息c)现场信息d)管理信息5.进程控制块的组织方式1)链接方式2)索引方式6.进程控制原语1)创建原语2)撤销原语3)阻塞原语4)唤醒原语7.程序代码#include<stdio.h>#include<iostream>using namespace std;void clrscr();void create();void run( );void exchange( );//唤出void kill( );void wakeUp( );//唤醒struct process_type{int pid;int priority;//优先次序int size;int state;//状态char info[10];};struct process_type internalMemory[20];int amount=0,hangUp=0,pid,flag=0;//数目,挂起void main( ){int n;int a;n=1;clrscr( );while(n==1){cout<<"\n********************************************";cout<<"\n* 进程演示系统 *";cout<<"\n********************************************";cout<<"\n 1.创建新的进程 2.查看运行进程 ";cout<<"\n 3.换出某个进程 4.杀死运行进程 ";cout<<"\n 5.唤醒某个进程¨ 6.退出系统 ";cout<<"\n*********************************************"<<endl;cout<<"请选择 ";cin>>a;switch(a){case 1:create( );break;case 2:run( );break;case 3:exchange();//换出break;case 4:kill();break;case 5:wakeUp();break;case 6:exit(0);default:n=0;}}}void create(){ //创建进程int i=0;if (amount>=20){cout<<" 内存已满,请先结束或换出进程";}else{for (i=0;i<20;i++){if (internalMemory[i].state==0){break;}}cout<<"请输入新进程的pid: "<<endl;cin>>internalMemory[ i ].pid;cout<<"请输入新进程的优先级: "<<endl;cin>>internalMemory[amount].priority;cout<<"请输入新进程的大小: "<<endl;cin>>internalMemory[amount].size;cout<<"请输入新进程的内容: "<<endl;cin>>internalMemory[amount].info;internalMemory[i].state=1;amount++;}}void clrscr()//清除内存空间{for (int i=0;i<19;i++){internalMemory[i].pid=0;internalMemory[i].priority=0;internalMemory[i].size=0;internalMemory[i].state=0;}amount=0;}void run(){for (int i=0;i<20;i++){if (internalMemory[i].state==1){cout<<"当前内存中的进程:\n"<<endl;cout<<"当前运行的进程: ";cout<<internalMemory[i].pid<<endl;cout<<"当前运行进程的优先级: ";cout<<internalMemory[i].priority<<endl;cout<<"当前运行进程占用的空间大小: ";cout<<internalMemory[i].size;}}}void exchange( ){//唤出优先级最小的进程if (!amount){cout<<"当前没有运行进程\n";return;}cout<<"\n输入换出进程的ID值: ";cin>>pid;for (int i=0;i<20;i++){if (pid==internalMemory[i].pid){if (internalMemory[i].state==1){internalMemory[i].state=2;hangUp++;cout<<"\n已经成功换出进程\n";}else if (internalMemory[i].state==0){cout<<"\n要换出的进程不存在";}else{cout<<"\n要换出的进程已被挂起\n";}flag=1;break;}}if (flag==0){cout<<"\n要换出的进程不存在";}}void kill( ){if (!amount){cout<<"当前没有运行进程\n";return;}cout<<"请输入要杀死的进程: ";cin>>pid;for (int i=0;i<20;i++){if (pid==internalMemory[i].pid){if (internalMemory[i].state==1){internalMemory[i].state=0;amount--;cout<<"此进程被杀死"<<pid;}else if (internalMemory[i].state==0){cout<<"\n要杀死的进程不存在\n";}else{cout<<"\n要杀死的进程已被挂起\n";}flag=1;break;}}if (!flag){cout<<"\n要杀死的进程不存在\n";}}void wakeUp(){if (!amount){cout<<"当前没有运行进程"<<endl;return;}if (!hangUp){cout<<"当前没有挂起进程";return;}cout<<"请输入pid: ";cin>>pid;for (int i=0;i<20;i++){if (pid==internalMemory[i].pid){flag=0;if (internalMemory[i].state==2){internalMemory[i].state=1;hangUp--;cout<<"已经成功唤醒进程\n";}else if (internalMemory[i].state==0){cout<<"\n要换醒的进程不存在\n";}else{cout<<"\n要唤醒的进程已被挂起\n";}break;}}if (flag){cout<<"\n要唤醒的进程已被挂起\n"<<endl;}}8.实现的结果。
实验2 进程状态转换及其PCB的变化
实验2进程状态转换及其PCB的变化1.目的自行编制模拟程序,通过形象化的状态显示,使学生理解进程的概念、进程之间的状态转换及其所带来的PCB内容、组织的变化,理解进程与其PCB间的一一对应关系。
2. 内容及要求1)设计并实现一个模拟进程状态转换及其相应PCB内容、组织结构变化的程序。
2)独立编写、调试程序。
进程的数目、进程的状态模型(三状态、五状态、七状态或其它)以及PCB的组织形式可自行选择。
3)合理设计与进程PCB相对应的数据结构。
PCB的内容要涵盖进程的基本信息、控制信息、资源需求及现场信息。
4)设计出可视性较好的界面,应能反映出进程状态的变化引起的对应PCB 内容、组织结构的变化。
5)代码书写要规范,要适当地加入注释。
6)鼓励在实验中加入新的观点或想法,并加以实现。
7)认真进行预习,完成预习报告。
8)实验完成后,要认真总结,完成实验报告。
3.程序流程图进程的三种基本状态及其转换如下图所示。
4.数据结构及说明在本实验中,主要的数据结构是PCB的数据结构,具体如下:struct process{char name; //进程名称int needtime; //进程所需要的运行时间int priority; //进程的优先级};5.源程序#include<stdio.h>#include<stdlib.h>#include<string.h>struct process{char name;int needtime;int priority;};struct process readyQueue[5];struct process run;struct process blockedQueue[5];const struct process null={NULL,0,0};int readyQueueHead=0;int blockedQueueHead=0;int cpuState=0;int cpuTime=0;void Order(struct process parameter[],int head);//将队列中的进程按优先级排列int Creat();void Dispath();int Timeout();int EventWait();int EventOccur();void Order(struct process parameter[],int head){int k,i;struct process temp;for(k=0;k<head-1;k++){for(i=0;i<head-k-1;i++){if(parameter[i].priority>=parameter[i+1].priority){temp=parameter[i];parameter[i]=parameter[i+1];parameter[i+1]=temp;}}}}int Creat(){if(readyQueueHead>=5){printf("The Ready Queue has been full\n");return 0;}label1:printf(" input new process name(must be a letter): \n");scanf("%c",&(readyQueue[readyQueueHead].name));getchar();int k;for( k=0;k<readyQueueHead;k++)if(readyQueue[readyQueueHead].name==readyQueue[k].name||readyQueue[rea dyQueueHead].name==readyQueue[k].name+32||readyQueue[readyQueueHead].na me==readyQueue[k].name-32){printf("the process is already exist!\n");goto label1;}for( k=0;k<blockedQueueHead;k++)if(readyQueue[readyQueueHead].name==blockedQueue[k].name||readyQueue[r eadyQueueHead].name==blockedQueue[k].name+32||readyQueue[readyQueueHea d].name==blockedQueue[k].name-32){printf("the process is already exist!\n");goto label1;}if(readyQueue[readyQueueHead].name==||readyQueue[readyQueueH ead].name==+32||readyQueue[readyQueueHead].name==-32) {printf("the process is already exist!\n");goto label1;}printf("input needtime (input a int number):\n");label2:scanf("%d",&(readyQueue[readyQueueHead].needtime));getchar();if(readyQueue[readyQueueHead].needtime<1||readyQueue[readyQueueHead].n eedtime>100){printf("please input the true needtime(1--100)\n");goto label2;}printf(" input the priority(1--10): \n");label3:scanf("%d",&(readyQueue[readyQueueHead].priority));getchar();if(readyQueue[readyQueueHead].priority<1||readyQueue[readyQueueHead].prio rity>10){printf("please 1--10!\n");goto label3;}readyQueueHead++;Order(readyQueue,readyQueueHead);return 0;}void Dispath(){if (cpuState==0){readyQueueHead--;if(readyQueue[readyQueueHead].needtime>0){Order(readyQueue,readyQueueHead);run=readyQueue[readyQueueHead];readyQueue[readyQueueHead]=null;cpuState=1;}else printf("no process in the Ready Queue\n");}else {Timeout();Dispath();}}int Timeout(){cpuTime++;if (==NULL) return 0;readyQueue[readyQueueHead]=run;run=null;cpuState=0;readyQueue[readyQueueHead].needtime--;if(readyQueue[readyQueueHead].needtime==0){printf("The process '%c' has finished",readyQueue[readyQueueHead].name);readyQueue[readyQueueHead]=null;return 0;}readyQueueHead++;Order(readyQueue,readyQueueHead);return 0;}int EventWait(){if(blockedQueueHead>=5){printf("error:The Blocked Queue has been full\n");return 0;}if(cpuState==0){printf("error:no process in CPU");return 0;}run.needtime--;blockedQueue[blockedQueueHead]=run;blockedQueueHead++;run=null;cpuState=0;cpuTime++;printf("The process is blocked!\n");return 0;}int EventOccur(){if(readyQueueHead>=5){printf("The Ready Queue has been full\n");return 0;}printf("Please input the process name whose event occured!\n");char name=getchar();getchar();int i;struct process temp;for(i=0;i<blockedQueueHead;i++){if(name==blockedQueue[i].name){blockedQueueHead--;readyQueue[readyQueueHead]=blockedQueue[i];readyQueueHead++;blockedQueue[i]=blockedQueue[blockedQueueHead];blockedQueue[blockedQueueHead]=null;Order(readyQueue,readyQueueHead);printf("The process %c is ready!\n",name);return 0;}}if(i==blockedQueueHead){printf("error:This process has not been blocked!\n");}return 0;}int Show(){printf("\nCPU time:%d\n",cpuTime);printf(" name needtime priority\n");printf("Ready Queue: ");int i;if(readyQueue[0].name!=NULL)for(i=readyQueueHead;i>0;i--)printf("%c %d %d\n ",readyQueue[i-1].name,readyQueue[i-1].needtime,readyQueue[i-1].priority);else printf("null");printf("\nRunning Process: ");if(==NULL) printf("null");else printf("%c %d %d\n ",,run.needtime,run.priority);printf("\nBlock Queue: ");if(blockedQueue[0].name==NULL) printf("null");else for(i=blockedQueueHead;i>0;i--)printf("%c %d %d\n ",blockedQueue[i-1].name,blockedQueue[i-1].needtime,blockedQueue[i-1].priority); }int main(){SELECT:printf("\n\n1:input new process\n2:Dispath\n3:Timeout\n4:EventWait\n5:EventOccurs\n0:exit\n");int select=getchar();getchar();switch(select){case '1':Creat();Show();break;case '2':Dispath();Show();break;case '3':Timeout();Show();break;case '4':EventWait();Show();break;case '5':EventOccur();Show();break;case '0':exit(0);default:printf("Please select from 0 to 5\n");}goto SELECT;return 0;6.运行结果及其说明(1)创建进程:按‘1’创建进程,进程被放入就绪队列,并按优先级从高到低排列。
操作系统实验进程状态转换及其PCB的变化
XX,a click to unlimited possibilities
汇报人:XX
目录
01 添 加 目 录 项 标 题
02 进 程 状 态 转 换
03 P C B 的 变 化
04 实 验 操 作 步 骤
05 实 验 结 果 与 讨 论
Part One
优先级:用于确定进程的调度 优先级
内存指针:指向进程在内存中 的起始地址
PCB在进程状态转换时的变化
PCB中进程状态的变化 PCB中进程优先级的变化 PCB中进程控制块的变化 PCB中进程调度信息的变化
PCB变化的意义
跟踪进程状态转 换:通过PCB的 变化,可以跟踪 进程在操作系统 中的状态转换, 从而更好地理解 操作系统的调度 机制。
单击添加章节标题
Part Two
进程状态转换
进程的三种基本状态
执行状态:进程已获得CPU, 正在执行
就绪状态:进程已获得除 CPU外的所有必要资源,等 待分配CPU
阻塞状态:进程因等待某个 条件(如I/O操作)而暂时
无法执行
进程状态的转换过程
进程创建状态:新进程从 无到有,创建并初始化 PCB
PCB变化的实现方式
进程状态转换:描述进程在执行过程中状态的变化过程,包括就绪态、 运行态、阻塞态等。
PCB结构:介绍PCB的结构和组成,包括进程名、进程标识符、进程状 态、优先级等。
PCB变化过程:描述在进程状态转换过程中,PCB中各字段的变化情况, 如状态、优先级、时间片等。
调度算法:介绍常见的进程调度算法,如先来先服务、最短作业优先、 优先级调度等,以及它们对PCB变化的影响。
实验结果分析
《操作系统原理》进程的创建与管理实验
《操作系统原理》进程的创建与管理实验1.目的要求(1)加深对进程概念的理解,明确进程和程序的区别。
(2)深入了解系统如何组织进程、创建进程。
(3)进一步认识如何实现处理器调度。
2.实验内容编写程序完成单处理机系统中的进程调度,要求采用时间片轮转调度算法。
实验具体包括:首先确定进程控制块的内容,进程控制块的组成方式;然后完成进程创建原语和进程调度原语;最后编写主函数对所做工作进行测试。
3.所需实验设施设备PC、windows操作系统4.教学形式及过程演示、学生独立完成5.设计思路(1)该程序是一个简单的时间片轮转调度算法的实现。
(2)首先定义了一个进程控制块(PCB)的结构体,包含进程的名称、到达时间、需要的运行时间、剩余运行时间和当前状态等信息。
然后定义了一个创建新节点的函数createNode,用于动态分配内存并初始化节点的数据。
接着定义了一个向循环链表中插入新节点的函数insertNodes,根据用户的输入创建新节点并插入到链表末尾。
然后定义了一个打印链表的函数printList,用于输出链表中所有节点的信息。
(3)接下来是冒泡排序函数bubbleSort,按照到达时间对链表中的节点进行排序。
然后定义了一个运行函数run,根据时间片大小依次运行进程,直到所有进程都完成运行。
最后在主函数中读取用户输入的进程数量和时间片大小,创建链表并调用run函数进行进程调度。
(4)整体思路是:先创建一个空链表,然后根据用户输入的进程数量,逐个创建新节点并插入到链表末尾。
然后对链表中的节点按照到达时间进行排序。
接着按照时间片大小依次运行进程,直到所有进程都完成运行。
最后输出链表中所有节点的信息。
6.知识原理操作系统通过进程控制块(PCB)来组织和管理进程。
(1)首先,操作系统会为每个进程创建一个PCB,PCB中包含了进程的重要信息,如进程号、进程状态、程序计数器、寄存器值、内存分配情况、打开文件等。
(2)当一个进程被创建时,操作系统会为其分配一个唯一的进程号,并将进程的相关信息填充到PCB中。
实验2进程状态转换及其PCB的变化
进程创建状态: PCB中记录进程 标识、父进程标 识等基本信息。
进程执行状态: PCB中增加记录 进程执行的CPU 寄存器信息,如 程序计数器、堆 栈指针等。
进程阻塞状态: PCB中记录进程 等待的资源或事 件,以及等待时 间和原因。
进程唤醒状态: PCB中更新进程 等待资源或事件 的状态,并重新 计算进程优先级。
就绪状态中,进程等待 CPU调度,一旦获得 CPU时间片,进程会从 就绪状态变为执行状态 。
进程因等待某个条件成立而无法继续执行 进程被阻塞,等待某个事件发生 进程被唤醒,条件成立,从阻塞状态转换到就绪状态 进程重新进入就绪队列,等待CPU调度执行
进程正常结束 进程异常结束 系统调用终止进程 父进程请求终止子进程
PART FIVE
准备实验器材和材料 按照实验指导书搭建实验电路 连接电源,启动实验设备
观察并记录实验现象和数据 分析实验结果,得出结论 清理实验现场,归还实验器材
准备实验器材和材料
按照实验指导书搭建实验 电路
连接电源,启动实验设备
观察并记录实验数据和现 象
分析实验结果,得出结论
清理实验现场,确保安全
实验结论:根据实验结果,得出实验结论,并指出实验的局限性和改进方向。
图表展示:利用图表展示实验结果,使数据更加直观易懂。
实验结果分析:对实验结果进行详细分析,包括数据对比、图表展示等 实验结论:根据实验结果得出结论,总结实验的成功与不足 实验收获:从实验中获得了哪些知识、技能和经验,如何应用到实际工作中 未来展望:对实验的未来发展进行展望,提出改进和优化的建议
XX,a click to unlimited possibilities
汇报人:XX
CONTENTS
操作系统进程调度模拟程序实验报告
操作系统进程调度模拟程序实验报告一、实验目的本次实验旨在通过编写一个模拟操作系统进程调度的程序,以加深对进程调度算法的理解。
二、实验内容1. 实现进程相关的数据结构:进程PCB(Process Control Block)。
2.实现进程的创建、撤销以及调度等操作函数。
3. 实现常见的进程调度算法:先来先服务(FCFS)、最短作业优先(SJF)、轮转调度(RR)、优先级调度(Priority)。
4.编写测试程序,验证实现的进程调度算法在不同场景下的表现。
三、实验过程及结果1.进程PCB的设计与实现进程PCB是进程的核心数据结构,用于存储和管理进程相关的信息,包括进程状态(就绪、运行、阻塞)、优先级、执行时间等。
2.进程的创建、撤销及调度函数的实现(1)进程创建函数:实现进程的创建,包括为其分配空间、初始化进程PCB等。
可以根据实际需求,设定进程的优先级、执行时间等属性。
(2)进程撤销函数:实现进程的撤销,包括释放其占用的资源、回收其使用的空间等。
(3)进程调度函数:根据不同的调度算法,实现进程的调度。
可以通过设置时间片大小、优先级设定等方式,实现不同调度算法的效果。
3.进程调度算法的设计与实现(1)先来先服务(FCFS)调度算法:按照进程到达的先后顺序,依次进行调度。
(2)最短作业优先(SJF)调度算法:根据进程的执行时间,选择执行时间最短的进程进行调度。
(3)轮转调度(RR)算法:按照时间片的大小进行调度,每个进程在一个时间片内执行,超过时间片后,暂停并进入等待队列,让其他进程执行。
(4)优先级调度(Priority)算法:根据进程的优先级,选择优先级最高的进程进行调度。
4.测试程序编写测试程序,模拟不同的进程到达顺序、执行时间和优先级等场景,验证不同调度算法的表现。
四、实验结果与分析通过测试程序的运行结果,观察不同调度算法的特点和效果。
可以得出以下结论:1.FCFS算法适用于进程到达时间差异较大的场景,保证了先到先服务。
进程切换实验报告
一、实验目的通过本次实验,了解进程切换的基本概念和过程,掌握进程切换的触发条件、切换过程以及切换开销,加深对进程调度和管理的理解。
二、实验环境操作系统:Linux编程语言:C语言开发环境:gcc编译器三、实验原理1. 进程切换的概念进程切换是指CPU从一个进程切换到另一个进程的过程。
在多进程系统中,操作系统为了保证各个进程的并发执行,需要实现进程切换。
进程切换是操作系统进程管理的核心内容。
2. 进程切换的触发条件(1)运行时间片用完:当进程运行一定的时间片后,CPU会强制将进程切换到就绪队列,等待下一次调度。
(2)高优先级进程就绪:当有更高优先级的进程进入就绪队列时,当前运行的进程会被切换。
(3)进程主动放弃CPU:如进程调用sleep()、yield()等函数,主动放弃CPU。
(4)异常和中断:如程序错误、硬件中断等,导致当前运行的进程切换。
3. 进程切换的过程(1)保存当前进程的状态:包括寄存器状态、程序计数器等。
(2)选择下一个要运行的进程:根据调度算法,从就绪队列中选择一个进程。
(3)恢复下一个进程的状态:将保存的状态恢复到CPU中。
(4)执行下一个进程:CPU开始执行新进程。
4. 进程切换开销进程切换过程中,需要保存和恢复进程状态,这会带来一定的开销。
进程切换开销包括:(1)时间开销:进程切换需要一定的时间,包括保存和恢复进程状态的时间。
(2)空间开销:进程切换需要一定的空间来保存和恢复进程状态。
四、实验内容1. 创建进程:使用C语言创建两个进程,其中一个为父进程,另一个为子进程。
2. 进程切换:在父进程中,使用sleep()函数使进程休眠一段时间,触发进程切换。
3. 观察进程切换:在父进程中,使用ps命令查看进程状态,观察进程切换过程。
4. 分析进程切换开销:通过比较父进程和子进程的运行时间,分析进程切换的开销。
五、实验步骤1. 编写C程序,创建父进程和子进程。
2. 在父进程中,使用sleep()函数使进程休眠一段时间。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验2进程状态转换及其PCB的变化1.目的自行编制模拟程序,通过形象化的状态显示,使学生理解进程的概念、进程之间的状态转换及其所带来的PCB内容、组织的变化,理解进程与其PCB间的一一对应关系。
2. 内容及要求1)设计并实现一个模拟进程状态转换及其相应PCB内容、组织结构变化的程序。
2)独立编写、调试程序。
进程的数目、进程的状态模型(三状态、五状态、七状态或其它)以及PCB的组织形式可自行选择。
3)合理设计与进程PCB相对应的数据结构。
PCB的内容要涵盖进程的基本信息、控制信息、资源需求及现场信息。
4)设计出可视性较好的界面,应能反映出进程状态的变化引起的对应PCB 内容、组织结构的变化。
5)代码书写要规范,要适当地加入注释。
6)鼓励在实验中加入新的观点或想法,并加以实现。
7)认真进行预习,完成预习报告。
8)实验完成后,要认真总结,完成实验报告。
3.程序流程图进程的三种基本状态及其转换如下图所示。
开始输入要执行的指令1?N 2?N 3?N 4?N 5?N 0?YY 结束N提示输入错误就绪队列已满?N创建进程Y提示就绪队列已满Y有进程处于运行状态?Y 该进程执行一个时间片后放回就绪队列N将就绪队列中优先级最高的进程放入运行队列有进程处于运行状态?Y该进程所需执行时间减1,并回到就绪队列Cputime++Y有进程处于运行状态?Y将该进程放入阻塞队列N提示无运行的进程输入事件发生的进程名称阻塞队列中有该进程?Y 将该进程放入就绪队列N提示该进程并未阻塞4.数据结构及说明在本实验中,主要的数据结构是PCB 的数据结构,具体如下: struct process{char name; //进程名称int needtime; //进程所需要的运行时间int priority; //进程的优先级};5.源程序#include<stdio.h>#include<stdlib.h>#include<string.h>struct process{char name;int needtime;int priority;};struct process readyQueue[5];struct process run;struct process blockedQueue[5];const struct process null={NULL,0,0};int readyQueueHead=0;int blockedQueueHead=0;int cpuState=0;int cpuTime=0;void Order(struct process parameter[],int head);//将队列中的进程按优先级排列int Creat();void Dispath();int Timeout();int EventWait();int EventOccur();void Order(struct process parameter[],int head){int k,i;struct process temp;for(k=0;k<head-1;k++){for(i=0;i<head-k-1;i++){if(parameter[i].priority>=parameter[i+1].priority){temp=parameter[i];parameter[i]=parameter[i+1];parameter[i+1]=temp;}}}}int Creat(){if(readyQueueHead>=5){printf("The Ready Queue has been full\n");return 0;}label1:printf(" input new process name(must be a letter): \n");scanf("%c",&(readyQueue[readyQueueHead].name));getchar();int k;for( k=0;k<readyQueueHead;k++)if(readyQueue[readyQueueHead].name==readyQueue[k].name||readyQueue[rea dyQueueHead].name==readyQueue[k].name+32||readyQueue[readyQueueHead].na me==readyQueue[k].name-32){printf("the process is already exist!\n");goto label1;}for( k=0;k<blockedQueueHead;k++)if(readyQueue[readyQueueHead].name==blockedQueue[k].name||readyQueue[r eadyQueueHead].name==blockedQueue[k].name+32||readyQueue[readyQueueHea d].name==blockedQueue[k].name-32){printf("the process is already exist!\n");goto label1;}if(readyQueue[readyQueueHead].name==||readyQueue[readyQueueH ead].name==+32||readyQueue[readyQueueHead].name==-32) {printf("the process is already exist!\n");goto label1;}printf("input needtime (input a int number):\n");label2:scanf("%d",&(readyQueue[readyQueueHead].needtime));getchar();if(readyQueue[readyQueueHead].needtime<1||readyQueue[readyQueueHead].n eedtime>100){printf("please input the true needtime(1--100)\n");goto label2;}printf(" input the priority(1--10): \n");label3:scanf("%d",&(readyQueue[readyQueueHead].priority));getchar();if(readyQueue[readyQueueHead].priority<1||readyQueue[readyQueueHead].prio rity>10){printf("please 1--10!\n");goto label3;}readyQueueHead++;Order(readyQueue,readyQueueHead);return 0;}void Dispath(){if (cpuState==0){readyQueueHead--;if(readyQueue[readyQueueHead].needtime>0){Order(readyQueue,readyQueueHead);run=readyQueue[readyQueueHead];readyQueue[readyQueueHead]=null;cpuState=1;}else printf("no process in the Ready Queue\n");}else {Timeout();Dispath();}}int Timeout(){cpuTime++;if (==NULL) return 0;readyQueue[readyQueueHead]=run;run=null;cpuState=0;readyQueue[readyQueueHead].needtime--;if(readyQueue[readyQueueHead].needtime==0){printf("The process '%c' has finished",readyQueue[readyQueueHead].name);readyQueue[readyQueueHead]=null;return 0;}readyQueueHead++;Order(readyQueue,readyQueueHead);return 0;}int EventWait(){if(blockedQueueHead>=5){printf("error:The Blocked Queue has been full\n");return 0;}if(cpuState==0){printf("error:no process in CPU");return 0;}run.needtime--;blockedQueue[blockedQueueHead]=run;blockedQueueHead++;run=null;cpuState=0;cpuTime++;printf("The process is blocked!\n");return 0;}int EventOccur(){if(readyQueueHead>=5){printf("The Ready Queue has been full\n");return 0;}printf("Please input the process name whose event occured!\n");char name=getchar();getchar();int i;struct process temp;for(i=0;i<blockedQueueHead;i++){if(name==blockedQueue[i].name){blockedQueueHead--;readyQueue[readyQueueHead]=blockedQueue[i];readyQueueHead++;blockedQueue[i]=blockedQueue[blockedQueueHead];blockedQueue[blockedQueueHead]=null;Order(readyQueue,readyQueueHead);printf("The process %c is ready!\n",name);return 0;}}if(i==blockedQueueHead){printf("error:This process has not been blocked!\n");}return 0;}int Show(){printf("\nCPU time:%d\n",cpuTime);printf(" name needtime priority\n");printf("Ready Queue: ");int i;if(readyQueue[0].name!=NULL)for(i=readyQueueHead;i>0;i--)printf("%c %d %d\n ",readyQueue[i-1].name,readyQueue[i-1].needtime,readyQueue[i-1].priority);else printf("null");printf("\nRunning Process: ");if(==NULL) printf("null");else printf("%c %d %d\n ",,run.needtime,run.priority);printf("\nBlock Queue: ");if(blockedQueue[0].name==NULL) printf("null");else for(i=blockedQueueHead;i>0;i--)printf("%c %d %d\n ",blockedQueue[i-1].name,blockedQueue[i-1].needtime,blockedQueue[i-1].priority); }int main(){SELECT:printf("\n\n1:input new process\n2:Dispath\n3:Timeout\n4:EventWait\n5:EventOccurs\n0:exit\n");int select=getchar();getchar();switch(select){case '1':Creat();Show();break;case '2':Dispath();Show();break;case '3':Timeout();Show();break;case '4':EventWait();Show();break;case '5':EventOccur();Show();break;case '0':exit(0);default:printf("Please select from 0 to 5\n");}goto SELECT;return 0;6.运行结果及其说明(1)创建进程:按‘1’创建进程,进程被放入就绪队列,并按优先级从高到低排列。