操作系统实验一模拟进程状态转换
操作系统进程调度模拟(全三分合集)
实验一进程调度实验一、目的要求用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
二、例题:设计一个有 N个进程共行的进程调度程序进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。
每个进程有一个进程控制块(PCB)表示。
进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。
进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。
进程的到达时间为进程输入的时间。
进程的运行时间以时间片为单位进行计算。
每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。
就绪进程获得CPU后都只能运行一个时间片。
用已占用CPU时间加1来表示。
如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。
每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。
重复以上过程,直到所要进程都完成为止。
调度算法的流程图如下图所示。
三.实验题:1、编写并调试一个模拟的进程调度程序,采用“最高优先数优先”调度算法对五个进程进行调度。
“最高优先数优先”调度算法的基本思想是把CPU分配给就绪队列中优先数最高的进程。
静态优先数是在创建进程时确定的,并在整个进程运行期间不再改变。
动态优先数是指进程的优先数在创建进程时可以给定一个初始值,并且可以按一定原则修改优先数。
例如:在进程获得一次CPU后就将其优先数减少1。
或者,进程等待的时间超过某一时限时增加其优先数的值,等等。
2、编写并调试一个模拟的进程调度程序,采用“轮转法”调度算法对五个进程进行调度。
轮转法可以是简单轮转法、可变时间片轮转法,或多队列轮转法。
实验一、进程调度实验报告
实验一、进程调度实验报告一、实验目的进程调度是操作系统中的核心功能之一,其目的是合理地分配 CPU 资源给各个进程,以提高系统的整体性能和资源利用率。
通过本次实验,我们旨在深入理解进程调度的原理和算法,掌握进程状态的转换,观察不同调度策略对系统性能的影响,并通过实际编程实现来提高我们的编程能力和对操作系统概念的理解。
二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 C++,开发工具为 Visual Studio 2019。
三、实验原理1、进程状态进程在其生命周期中会经历不同的状态,包括就绪态、运行态和阻塞态。
就绪态表示进程已经准备好执行,只等待 CPU 分配;运行态表示进程正在 CPU 上执行;阻塞态表示进程由于等待某个事件(如 I/O操作完成)而暂时无法执行。
2、调度算法常见的进程调度算法有先来先服务(FCFS)、短作业优先(SJF)、时间片轮转(RR)等。
先来先服务算法按照进程到达的先后顺序进行调度。
短作业优先算法优先调度执行时间短的进程。
时间片轮转算法将 CPU 时间划分成固定大小的时间片,每个进程轮流获得一个时间片执行。
四、实验内容1、设计并实现一个简单的进程调度模拟器定义进程结构体,包含进程 ID、到达时间、执行时间、剩余时间等信息。
实现进程的创建、插入、删除等操作。
实现不同的调度算法。
2、对不同调度算法进行性能测试生成一组具有不同到达时间和执行时间的进程。
分别采用先来先服务、短作业优先和时间片轮转算法进行调度。
记录每个算法下的平均周转时间、平均等待时间等性能指标。
五、实验步骤1、进程结构体的定义```c++struct Process {int pid;int arrivalTime;int executionTime;int remainingTime;int finishTime;int waitingTime;int turnaroundTime;};```2、进程创建函数```c++void createProcess(Process processes, int& numProcesses, int pid, int arrivalTime, int executionTime) {processesnumProcessespid = pid;processesnumProcessesarrivalTime = arrivalTime;processesnumProcessesexecutionTime = executionTime;processesnumProcessesremainingTime = executionTime;numProcesses++;}```3、先来先服务调度算法实现```c++void fcfsScheduling(Process processes, int numProcesses) {int currentTime = 0;for (int i = 0; i < numProcesses; i++){if (currentTime < processesiarrivalTime) {currentTime = processesiarrivalTime;}processesistartTime = currentTime;currentTime += processesiexecutionTime;processesifinishTime = currentTime;processesiwaitingTime = processesistartTime processesiarrivalTime;processesiturnaroundTime = processesifinishTime processesiarrivalTime;}}```4、短作业优先调度算法实现```c++void sjfScheduling(Process processes, int numProcesses) {int currentTime = 0;int minExecutionTime, selectedProcess;bool found;while (true) {found = false;minExecutionTime = INT_MAX;selectedProcess =-1;for (int i = 0; i < numProcesses; i++){if (processesiarrivalTime <= currentTime &&processesiremainingTime < minExecutionTime &&processesiremainingTime > 0) {found = true;minExecutionTime = processesiremainingTime;selectedProcess = i;}}if (!found) {break;}processesselectedProcessstartTime = currentTime;currentTime += processesselectedProcessremainingTime;processesselectedProcessfinishTime = currentTime;processesselectedProcesswaitingTime =processesselectedProcessstartTime processesselectedProcessarrivalTime;processesselectedProcessturnaroundTime =processesselectedProcessfinishTime processesselectedProcessarrivalTime;processesselectedProcessremainingTime = 0;}}```5、时间片轮转调度算法实现```c++void rrScheduling(Process processes, int numProcesses, int timeSlice) {int currentTime = 0;Queue<int> readyQueue;for (int i = 0; i < numProcesses; i++){readyQueueenqueue(i);}while (!readyQueueisEmpty()){int currentProcess = readyQueuedequeue();if (processescurrentProcessarrivalTime > currentTime) {currentTime = processescurrentProcessarrivalTime;}if (processescurrentProcessremainingTime <= timeSlice) {currentTime += processescurrentProcessremainingTime;processescurrentProcessfinishTime = currentTime;processescurrentProcesswaitingTime =processescurrentProcessstartTime processescurrentProcessarrivalTime;processescurrentProcessturnaroundTime =processescurrentProcessfinishTime processescurrentProcessarrivalTime;processescurrentProcessremainingTime = 0;} else {currentTime += timeSlice;processescurrentProcessremainingTime = timeSlice;readyQueueenqueue(currentProcess);}}}```6、性能指标计算函数```c++void calculatePerformanceMetrics(Process processes, int numProcesses, double& averageWaitingTime, double& averageTurnaroundTime) {double totalWaitingTime = 0, totalTurnaroundTime = 0;for (int i = 0; i < numProcesses; i++){totalWaitingTime += processesiwaitingTime;totalTurnaroundTime += processesiturnaroundTime;}averageWaitingTime = totalWaitingTime / numProcesses; averageTurnaroundTime = totalTurnaroundTime / numProcesses;}```7、主函数```c++int main(){Process processes100;int numProcesses = 0;//创建进程createProcess(processes, numProcesses, 1, 0, 5);createProcess(processes, numProcesses, 2, 1, 3);createProcess(processes, numProcesses, 3, 2, 4);createProcess(processes, numProcesses, 4, 3, 2);//先来先服务调度fcfsScheduling(processes, numProcesses);double fcfsAverageWaitingTime, fcfsAverageTurnaroundTime;calculatePerformanceMetrics(processes, numProcesses, fcfsAverageWaitingTime, fcfsAverageTurnaroundTime);cout <<"先来先服务调度的平均等待时间:"<<fcfsAverageWaitingTime << endl;cout <<"先来先服务调度的平均周转时间:"<<fcfsAverageTurnaroundTime << endl;//短作业优先调度sjfScheduling(processes, numProcesses);double sjfAverageWaitingTime, sjfAverageTurnaroundTime;calculatePerformanceMetrics(processes, numProcesses, sjfAverageWaitingTime, sjfAverageTurnaroundTime);cout <<"短作业优先调度的平均等待时间:"<<sjfAverageWaitingTime << endl;cout <<"短作业优先调度的平均周转时间:"<<sjfAverageTurnaroundTime << endl;//时间片轮转调度(时间片为 2)rrScheduling(processes, numProcesses, 2);double rrAverageWaitingTime, rrAverageTurnaroundTime;calculatePerformanceMetrics(processes, numProcesses, rrAverageWaitingTime, rrAverageTurnaroundTime);cout <<"时间片轮转调度(时间片为 2)的平均等待时间:"<< rrAverageWaitingTime << endl;cout <<"时间片轮转调度(时间片为 2)的平均周转时间:"<< rrAverageTurnaroundTime << endl;return 0;}```六、实验结果与分析1、先来先服务调度平均等待时间:40平均周转时间:85分析:先来先服务调度算法简单直观,但对于短作业可能会造成较长的等待时间,导致平均等待时间和平均周转时间较长。
操作系统实验一模拟进程状态转换
操作系统实验一模拟进程状态转换四、运行结果:图1 创建2个进程,因为这时cpu空闲所以内核调度,b优先级高先执行图2 超时,因为这时cpu空闲所以内核调度,b优先级还是比a高所以先执行图3 2个进程均被阻塞,其中一旦进程被阻塞就会引发调度图4 唤醒1个进程,从阻塞队列取队首放到就绪队列队尾,由于这时cpu空闲所以内核调度五、源代码:#include<cstdio>#include<algorithm>using namespace std;int Ready_len=0;int Blocked_len=0;int CPU_state=0;struct PCB{char name;int priority;int needtime;bool operator < (const PCB &b) const{return priority>b.priority;}};PCB Ready[100];PCB Blocked[100];PCB Cpu;bool dispatch();bool creat(int NUM){//创建一个新的进程while(NUM--){printf("输入进程名(一个字符)、所需时间(一个整数)、优先级(一个整数): \n");scanf("%s%d%d",&(Ready[Ready_len].name),&(Ready[Ready_len ].needtime),&(Ready[Ready_len].priority));getchar();Ready_len++;}if(CPU_state==0)//如果CPU空闲,则调度dispatch();}bool dispatch(){if(CPU_state==0){if(Ready_len!=0){sort(Ready,Ready+Ready_len);=Ready[0].name;Cpu.needtime=Ready[0].needtime;Cpu .priority=Ready[0].priority;if(Ready_len!=1)//就绪队列剔除队首元素for(int indx=1;indx<Ready_len;indx++){Ready[indx-1].name=Ready[indx].name;Ready[indx-1].needtime= Ready[indx].needtime;Ready[indx-1].priority=Ready[indx].priority;}Ready_len--;CPU_state=1;printf("***%c进程送往CPU执行\n",);Cpu.needtime--;Cpu.priority--;}else{printf("***就绪队列为空,无法调度\n");return false;}}else{printf("***CPU忙,无法调度\n");}}bool time_out(){if(CPU_state==1){if(Cpu.needtime==0)printf("***%c时间片用完,并且执行完毕,被释放\n",);else{Ready[Ready_len].name=;Ready[Ready_len].needtime= Cpu.needtime;Ready[Ready_len].priority=Cpu.priority;Ready_len++;printf("***%c时间片用完\n",);}CPU_state=0;=0;Cpu.needtime=0;Cpu.priority=0;if(Ready_len!=0)//时间片用完,如果就绪队列不为空,则调度dispatch();}else{printf("***没有进程在CPU中,无法超时\n");}}bool event_wait(){if(CPU_state==1){Blocked[Blocked_len].name=;Blocked[Blocked_len].n eedtime=Cpu.needtime;Blocked[Blocked_len].priority=Cpu.priority;Blocked_len++;printf("***%c被阻塞\n",);CPU_state=0;if(Ready_len!=0)//进程被阻塞,如果就绪队列不为空,则调度dispatch();}elseprintf("***没有进程在CPU中,无法阻塞\n");}bool event_occur(){if(Blocked_len!=0){//sort(Blocked,Blocked+Blocked_len);Ready[Ready_len].name=Blocked[0].name;Ready[Ready_len].nee dtime=Blocked[0].needtime;Ready[Ready_len].priority=Blocked[0]. priority;Ready_len++;if(Blocked_len!=1)//阻塞队列剔除队首元素for(int indx=1;indx<Blocked_len;indx++){Blocked[indx-1].name=Blocked[indx].name;Blocked[indx-1].needti me=Blocked[indx].needtime;Blocked[indx-1].priority=Blocked[indx]. priority;}Blocked_len--;//printf("%d %d",Blocked_len,Ready_len);printf("***%c被唤醒\n",Ready[Ready_len-1].name);if(CPU_state==0)//如果CPU空闲,则调度dispatch();//printf("%d %d",Blocked_len,Ready_len);}elseprintf("***阻塞队列为空,无法唤醒\n");}int main(){int Cputime=1;while(1){printf("\n1:New\t\t\t2:Dispatch\n");printf("3:Timeout\t\t4:Event wait\n");printf("5:Event occur\t\t0:exit\n");printf("输入1--5实现相应的功能:\n");int select;scanf("%d",&select);getchar();switch(select){case 1:int num;printf("输入要创建的进程数:\n");scanf("%d",&num);getchar();creat(num);break;case 2:dispatch();break;case 3:time_out();break;case 4:event_wait();break;case 5:event_occur();break;case 0:exit(0);break;}printf("****************************Cputime:%3d********************* *******\n",Cputime);printf("状态\t\t进程名\t\t需要时间\t\t优先级\n");if(CPU_state){//显示CPU中的进程printf("Running:\t%c\t\t",);printf("%d\t\t\t",Cpu.needtime);printf("%d\n",Cpu.priority);}if(Ready_len){//显示Ready队列中的进程for(int a=0;a<Ready_len;a++){printf("Ready%d:\t\t",a);printf("%c\t\t",Ready[a].name);printf("%d\t\t\t",Ready[a].needtime);printf("%d\n",Ready[a].priority);}}if(Blocked_len){//显示Blocked队列中的程序for(int b=0;b<Blocked_len;b++){printf("Blocked%d:\t",b);printf("%c\t\t",Blocked[b].name);printf("%d\t\t\t",Blocked[b].needtime);printf("%d\n",Blocked[b].priority);}}printf("**************************************************************** ***\n");Cputime++;} }。
操作系统实验报告进程状态转换
实验进程状态转换及其PCB的变化、程序流程图:、使用的数据结构及说明:在本实验中,主要用到的数据结构是PCB的结构,其中PCB的数据结构如下: struct PCB {int P_ld;char P_Name[10];char P_State[10];int P_Ru ntime;int P_Requiry; struct PCB * n ext ;l -//PCB 的ID 号//PCB的名称//PCB状态//PCB的所需要的运行时间//PCB所需要的资源要求//PCB块的下一个指针其中,P_Id,和P_Name 用来标示一个进程,而P_State用来标示进程的五种状态:Create_state,Ready_state,Block_state,Run_state,Exit_state 。
P_Runtime 标示要完成一个进程所需 要的时间。
P_Requiry 标示一个进程的执行所需要的其他条件, 当其他的条件满足, 则 P_Requiry 置1,否则置0。
Struct PCB * next 用来指向同一队列中的下一个PCB 块。
三、程序源代码 :#include"stdlib.h" #include"stdio.h" #include"string.h"/********** globle structure and viable ******/ struct PCB//PCB 的 ID 号//PCB 的名称//PCB 状态//PCB 的所需要的运行时间 //PCB 所需要的资源要求 //PCB 块的下一个指针{ p=*head; q=p->next;p=q;q=q->next;}// 将节点插入队列{int P_Id;char P_Name[10]; char P_State[10]; int P_Runtime; int P_Requiry; struct PCB * next ; } ;struct PCB * Create_state; struct PCB * Run_state; struct PCB * Ready_state; struct PCB * Block_state; struct PCB * Exit_state; int signal4=0; int signal5=0;// 创建状态 // 运行状态 // 就绪状态 // 阻塞状态// 退出状态 // 标示进程 // 标示进程的完成状态 的完成状态void InsertQueue(struct PCB **head,struct PCB *node){struct PCB * p,*q; node->next=NULL; if(*head==NULL){*head=node;}Else/* insert node function */// 如果队列为空// 队列不空while(q!=NULL) {// 找到最后的元素位置p->next=node;void DeleteQueue(struct PCB **head,struct PCB *node) {struct PCB *p,*q; q=*head;if(node->P_Requiry)printf("this process resource is ready \n");elseprintf("this process resource is not ready ! \n");}void DispatchToBlock(struct PCB *node) // /* dispatch to block function*/ { // 调度到阻塞状态的函数//struct PCB *p=(struct PCB *)malloc(sizeof(struct PCB));if(!node->P_Requiry) // 如果所需要的资源没有满足则,调度到阻塞状态 { strcpy(node->P_State,"block");InsertQueue(&Block_state,node); // 插入到阻塞队列 Display_Process(node);if(*head==NULL||node==NULL) return ; if(*head==node) { *head=(*head)->next; return; } Else { while(q->next!=p&&q->next!=NULL)q=q->next; q=p->next; p->next=NULL;}} void Display_Process(struct PCB * node) {printf("\n\nthis process Id is printf("this process name is printf("this process state is printf("this process Runtime is // 如果队列为空,返回 // 如果要删除的元素是队首元素// 如果不是队列的首元素// 打印进程状态的元素函数 : %d \n",node->P_Id); : %s \n",node->P_Name); : on %s \n ",node->P_State); : %d \n",node->P_Runtime);// 撤销进程,从队列中删除元素void DispatchToReady(struct PCB *node) // dispatch to ready state{ // 调度到就绪状态的函数 if(node->P_Requiry) // 如果所需的资源满足,则调度{strcpy(node->P_State,"Ready");InsertQueue(&Ready_state,node); Display_Process(node);}}void DispatchBlockToReady() //dispatch the process to readyqueueInsertQueue(&Ready_state,p);printf("process4 will be in the state of ready!\n"); Display_Process(p);} if(signal5&&p->P_Id==5){DeleteQueue(&Block_state,p); strcpy(p->P_State,"ready");InsertQueue(&Ready_state,p);printf("process5 will be in the state of ready!\n"); Display_Process(p);} } }void Create_Process(){int i;struct PCB *p; char name[10];{ struct PCB*p,*q;q=Block_state; while(q!=NULL){p=q; q=q->next;if(signal4&&p->P_Id==4){DeleteQueue(&Block_state,p); strcpy(p->P_State,"ready");// 从阻塞状态调度到就绪状态函数 // 如果阻塞状态队列不空//如果所需要的资源满足// 创建进程函数strcpy(name,"process"); // 动态创建 2 个处于阻塞状态的进程p=(struct PCB *)malloc(sizeof(struct PCB)); p->P_Id=i; name[7]=i+'0';name[8]='\0'; strcpy(p->P_Name,name); strcpy(p->P_State,"create");p->P_Runtime=1; // 所需要的时间片为 1 p->P_Requiry=0; Display_Process(p); sleep(4);printf(" \n process%d will be in the state of Block, waiting the resource ready \n\n",i); DispatchToBlock(p); // 同时调度到阻塞队列// 创建 4 个就绪状态的队列p=(struct PCB *)malloc(sizeof(struct PCB)); p->P_Id=i; name[7]=i+'0'; name[8]='\0';strcpy(p->P_Name,name); strcpy(p->P_State,"create"); p->P_Requiry=1; p->P_Runtime=2; elsep->P_Runtime=1; Display_Process(p); sleep(4);printf(" \n process%d will be in the state of Ready, waiting to run \n\n",i); DispatchToReady(p);void display(struct PCB **head) {struct PCB *p,*q; p=*head;for(i=1;i<3;i++){for(i=3;i<7;i++){if(i==6)// 在这里个进程 6while(p!=NULL) { sleep(2);//printf("\n\n///////////////////////////////////\n"); printf("\n\nthis process Id is printf("this process name is printf("this process state is printf("this process Runtime is if(p->P_Requiry)printf("this process resource is ready \n");elseprintf("this process resource is not ready ! \n"); p=p->next;} }{printf("this process is not finished,will be dispatch to the ready queue!!\n"); DeleteQueue(&Ready_state,p);strcpy(p->P_State,"ready"); InsertQueue(&Ready_state,p);Display_Process(p);}Else // 执行完成,则跳出,并发送相应的信息 {printf("\n\nProcess%d is finished and will be in the state of exit!\n\n",p->P_Id);if(p->P_Id==4) signal4=1; if(p->P_Id==5) signal5=1; } if(signal4||signal5)DispatchBlockToReady(); // 如果资源满足,则将进程调度到就绪队列 q=q->next;p=q;}if(q==NULL) printf("\nthere is no process ready!\n STOP Machine!!!\n");}int main(int argc,char * argv[]) // 主函数: %d \n",p->P_Id); : %s \n",p->P_Name); : on %s \n ",p->P_State); : %d \n",p->P_Runtime);void Process_Run(){struct PCB *p,*q; p=Ready_state; q=p;while(p!=NULL){if(p->P_Runtime<=0) break; strcpy(p->P_State,"running"); Display_Process(p);p->P_Runtime=p->P_Runtime-1; sleep(4);if(p->P_Runtime>0)// 进程运行函数// 就绪队列不空则继续执行 // 如果时间片执行完了,则跳出循环// 没有完成,则进入就绪队列{int i;char c='c'; // 界面printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \n"); printf(" Ding Hai bo\n");printf(" ..... P ress s to start the process ...... \n");scanf("%c",&c);while(1){if(c=='s')break; scanf("%c",&c);}Create_Process(); // 调用创建进程函数printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); printf("\n>>>>>>> Display the Ready queue >>>>>>>>>>>>>>>\n"); sleep(5);display(&Ready_state); //////////////// 显示就绪队列里的进程printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");printf("\n>>>>>>>> Display the Block queue >>>>>>>>>>>>\n");sleep(5); // 显示阻塞队列函数display(&Block_state); /////////////////////printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n\n");printf("\n>>>>>>>> Now the process start to run >>>>>>>>>>>\n");sleep(5);Process_Run(); // 调用进程运行函数}四、运行结果及说明:运行结果的截图:下面的运行结果是程序执行的每一步进程调度的显示,从进程的创建到进程的执行,结束,每一步进程调度都有显示。
操作系统进程的三种状态的转换实验报告
3.设计出可视性较好的界面,应能反映出进程状态的变化引起的对应内容。
4.代码书写要规范,要适当地加入注释。
5.编译并调试自己编写的程序,是程序编译成功。
6.检查运行的结果是否正确。
四、实验结果(含算法说明、程序、数据记录及分析等,可附页)
五、实验思考题
利用C语言编写了一个模拟Windows进程三种状态之间的转换的程序,虽然肥城精简,但是我从中学到的很多知识点,学会了编写程序时的一些技巧,为自己以后更加深造打下了坚实的基础和使自己更好的理解Windows如何更好的管理进程。
六、实验总结(含实验心得体会,收获与不足等)
通过这次实验让我受益匪浅,不仅明白了自己以前不知道如何定义和应用结构体,还提高了自己的编程能力,调试程序的能力,使自己的编程能力有了大幅度的提高。使自己更好的理解进程的概念和进程的三种状态之间转换的过程和他们之间的关系。为自己以后复习打下了夯实的基础。
1)根据课本第三章的内容设计并实现一个模拟进程状态转换。
2)独立编写和调试程序。进程的数目,进程的状态模型自行选择。
3)合理设计进程相对应的数据结构,内容要包括进程的基本信息。
4)是进程的三种状态之间的转化清晰的显示。
三、实验过程及步骤(包含使用软件或实验设备等情况)
1.打开DEV-C++,新建一个源代码文件
实验报告
实验名称
进程三种状态的转换
专业
计算机
课程名称
操作系统
指导老师
张海燕
班级
二表一班
姓名
刘广法
学号
11100140109
评分
实验地点
1cபைடு நூலகம்6217
进程的管理实验报告结论
一、实验背景及目的进程是操作系统中基本的活动单位,进程管理是操作系统核心功能之一。
为了深入理解进程的概念、进程状态转换、进程同步与互斥等知识,我们进行了进程管理实验。
本次实验旨在通过编写程序,模拟进程的创建、调度、同步与互斥等操作,加深对进程管理的理解。
二、实验内容及方法1. 进程创建与状态转换(1)使用系统调用fork()创建子进程,观察父进程和子进程的状态转换过程。
(2)使用系统调用exec()替换子进程的内容,观察子进程状态变化。
2. 进程调度(1)编写进程调度程序,实现最高优先数优先调度算法和先来先服务调度算法。
(2)模拟进程就绪队列,观察调度算法对进程执行顺序的影响。
3. 进程同步与互斥(1)使用信号量实现进程同步,观察进程同步效果。
(2)使用互斥锁实现进程互斥,观察进程互斥效果。
4. 进程通信(1)使用管道实现进程间通信,观察通信效果。
(2)使用共享内存实现进程间通信,观察通信效果。
三、实验结果与分析1. 进程创建与状态转换实验结果显示,使用fork()创建子进程后,父进程和子进程的状态均为运行态。
当父进程调用exec()替换子进程内容后,子进程状态变为僵尸态,父进程状态变为运行态。
这说明进程在创建和替换过程中,其状态发生了相应的变化。
2. 进程调度实验结果显示,最高优先数优先调度算法和先来先服务调度算法均能正确执行。
最高优先数优先调度算法下,优先级高的进程先执行;先来先服务调度算法下,先到达的进程先执行。
这说明两种调度算法均能实现进程的合理调度。
3. 进程同步与互斥实验结果显示,使用信号量实现进程同步时,进程能正确地按照规定的顺序执行;使用互斥锁实现进程互斥时,进程能正确地实现互斥访问共享资源。
这说明信号量和互斥锁在进程同步与互斥方面具有重要作用。
4. 进程通信实验结果显示,使用管道实现进程间通信时,进程能正确地接收和发送数据;使用共享内存实现进程间通信时,进程能正确地访问共享内存中的数据。
操作系统-进程的状态与转换
操作系统-进程的状态与转换进程的状态与转换状态进程是程序的⼀次执⾏。
在这个执⾏过程中,有时进程正在被CPU处理,有时⼜需要等待CPU服务,可见,进程的状态是会有各种变化。
为了⽅便对各个进程的管理,操作系统需要将进程合理地划分为⼏种状态。
三种基本状态运⾏态(Running)CPU√ 其他所需资源×占有CPU,并在CPU上运⾏注意:单核处理机环境下,每⼀时刻最多只有⼀个进程处于运⾏态。
(双核环境下可以同时有两个进程处于运⾏态)。
就绪态(Ready)CPU√ 其他所需资源×已经具备运⾏条件,但由于没有空闲CPU,⽽暂时不能运⾏进程已经拥有了除了处理机之外所有需要地资源,⼀旦获得处理机,即可⽴即进⼊运⾏态开始运⾏。
即:万事俱备,只⽋CPU。
阻塞态(Waiting/Blocked,⼜称等待态)CPU× 其他所需资源×因等待某⼀事件⽽暂时不能运⾏如:等待操作系统分配打印机,等待读磁盘操作地结果。
CPU是计算机中最昂贵地部件,为了提⾼CPU地利⽤率,需要先将其他进程需要地资源分配到位,才能得到CPU的服务。
另外两种状态创建态(New,⼜名:新建态)进程正在被创建,操作系统为进程分配资源、初始化PCB。
终⽌态(Terminated,⼜称:结束态)进程正在从系统中撤销,操作系统会回收进程拥有的资源。
进程状态的转换图⽚来⾃王道考研B站视频截图就绪态=>运⾏态进程被调度运⾏态=>就绪态时间⽚到,或CPU被其他⾼优先级的进程抢占运⾏态=>阻塞态等待系统资源分配,或等待某事件发⽣(主动⾏为)阻塞态=>就绪态资源分配到位,等待事件的发⽣(被动⾏为)⼏个注意点运⾏态=>阻塞态是⼀种进程⾃⾝作出的主动⾏为阻塞态=>就绪态不是进程⾃⾝能控制的,是⼀种被动⾏为不能由阻塞态直接转换为运⾏态,也不能由就绪态直接转换为阻塞态(因为进⼊阻塞态是进程主动请求的,必然需要进程在运⾏时才能发出这种请求)。
操作系统进程管理实验报告
操作系统进程管理实验报告一、引言在现代计算机科学中,操作系统的进程管理是确保系统高效运行的关键环节。
本实验旨在通过观察和分析操作系统的进程管理行为,深入理解进程的创建、运行和终止过程,以及操作系统如何对进程进行调度和资源分配。
二、实验目标1、理解进程的基本概念、进程状态及转换。
2、掌握进程的创建、终止和调度方法。
3、观察和分析进程在运行过程中的资源消耗和调度行为。
4、分析操作系统对进程的资源分配和调度策略对系统性能的影响。
三、实验环境与工具本实验在Linux操作系统上进行,使用GNU/Linux环境下的工具进行进程的创建、监控和调度。
四、实验步骤与记录1、创建进程:使用shell命令“fork”创建一个新的进程。
记录下父进程和子进程的PID,以及它们在内存中的状态。
2、进程状态观察:使用“ps”命令查看当前运行进程的状态,包括进程的PID、运行时间、CPU使用率等。
同时,使用“top”命令实时监控系统的CPU、内存等资源的使用情况。
3、进程调度:在“crontab”中设置定时任务,观察系统如何根据预设的调度策略分配CPU资源给各个进程。
4、资源分配:通过修改进程的优先级(使用“nice”命令),观察系统如何调整资源分配策略。
5、终止进程:使用“kill”命令终止一个进程,并观察系统如何处理该进程占用的资源。
五、实验结果与分析1、创建进程:通过“fork”系统调用,成功创建了一个新的进程,并获取了父进程和子进程的PID。
在内存中,父进程和子进程的状态分别为“running”和“ready”。
2、进程状态观察:使用“ps”命令可以看到父进程和子进程的状态均为“running”,同时显示了它们的CPU使用率和运行时间等信息。
通过“top”命令,可以实时监控系统的CPU、内存等资源的使用情况,为进一步分析提供了数据支持。
3、进程调度:在“crontab”中设置定时任务后,系统会根据预设的调度策略以及各个进程的运行状态,动态地分配CPU资源给各个进程。
进程管理实验报告代码
一、实验目的1. 理解进程的概念和进程状态转换。
2. 掌握进程同步与互斥的基本方法。
3. 学习使用信号量实现进程同步与互斥。
4. 熟悉进程调度算法。
二、实验环境1. 操作系统:Windows/Linux2. 编程语言:C/C++3. 开发工具:Visual Studio/Code::Blocks三、实验内容1. 进程状态转换2. 进程同步与互斥3. 信号量实现进程同步与互斥4. 进程调度算法四、实验步骤1. 进程状态转换```c#include <stdio.h>#include <unistd.h>void print_status(int state) {switch (state) {case 1: printf("创建状态\n"); break; case 2: printf("就绪状态\n"); break;case 3: printf("运行状态\n"); break; case 4: printf("阻塞状态\n"); break; case 5: printf("终止状态\n"); break; default: printf("未知状态\n"); break; }}int main() {int state = 1;print_status(state);sleep(1);state = 2;print_status(state);sleep(1);state = 3;print_status(state);sleep(1);state = 4;print_status(state);sleep(1);state = 5;print_status(state);return 0;}```2. 进程同步与互斥```c#include <stdio.h>#include <pthread.h>pthread_mutex_t lock;void thread_func(void arg) {pthread_mutex_lock(&lock);printf("线程 %d 进入临界区\n", (int )arg);sleep(2);printf("线程 %d 离开临界区\n", (int )arg);pthread_mutex_unlock(&lock);return NULL;}int main() {pthread_t tid1, tid2;int arg1 = 1, arg2 = 2;pthread_mutex_init(&lock, NULL);pthread_create(&tid1, NULL, thread_func, &arg1); pthread_create(&tid2, NULL, thread_func, &arg2); pthread_join(tid1, NULL);pthread_join(tid2, NULL);pthread_mutex_destroy(&lock);return 0;}```3. 信号量实现进程同步与互斥```c#include <stdio.h>#include <pthread.h>#include <semaphore.h>sem_t sem;void thread_func(void arg) {sem_wait(&sem);printf("线程 %d 进入临界区\n", (int )arg);sleep(2);printf("线程 %d 离开临界区\n", (int )arg);sem_post(&sem);return NULL;}int main() {pthread_t tid1, tid2;int arg1 = 1, arg2 = 2;sem_init(&sem, 0, 1);pthread_create(&tid1, NULL, thread_func, &arg1); pthread_create(&tid2, NULL, thread_func, &arg2);pthread_join(tid1, NULL);pthread_join(tid2, NULL);sem_destroy(&sem);return 0;}```4. 进程调度算法```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#define MAX_PROCESSES 5typedef struct {int pid;int arrival_time;int burst_time;int wait_time;int turnaround_time;} Process;int compare(const void a, const void b) {Process proc1 = (Process )a;Process proc2 = (Process )b;return proc1->arrival_time - proc2->arrival_time;}void fcfs(Process processes[], int n) {processes[0].wait_time = 0;processes[0].turnaround_time = processes[0].burst_time;for (int i = 1; i < n; i++) {processes[i].wait_time = processes[i - 1].turnaround_time + processes[i].arrival_time - processes[i].burst_time;processes[i].turnaround_time = processes[i].wait_time + processes[i].burst_time;}}int main() {Process processes[MAX_PROCESSES] = {{1, 0, 3, 0, 0},{2, 1, 6, 0, 0},{3, 4, 4, 0, 0},{4, 6, 5, 0, 0},{5, 8, 2, 0, 0}};qsort(processes, MAX_PROCESSES, sizeof(Process), compare);fcfs(processes, MAX_PROCESSES);for (int i = 0; i < MAX_PROCESSES; i++) {printf("PID: %d, Wait Time: %d, Turnaround Time: %d\n", processes[i].pid, processes[i].wait_time, processes[i].turnaround_time);}return 0;}```五、实验结果与分析通过以上实验,我们了解了进程状态转换、进程同步与互斥、信号量实现进程同步与互斥以及进程调度算法。
进程状态转换
3.2.4 被挂起的进程交换的需要前面描述的三个基本状态(就绪态、运行态和阻塞态)提供了一种为进程行为建立模型的系统方法,并指导操作系统的实现。
许多实际的操作系统都是按照这样的三种状态进行具体构造的。
但是,可以证明往模型中增加其他状态也是合理的。
为了说明加入新状态的好处,考虑一个没有使用虚拟内存的系统,每个被执行的进程必须完全载入内存,因此,图3.8b 中,所有队列中的所有进程必须驻留在内存中。
所有这些设计机制的原因都是由于I/O 活动比计算速度慢很多,因此在单道程序系统中的处理器在大多数时候是空闲的。
但是图3.8b 的方案并没有完全解决这个问题。
在这种情况下,内存保存有多个进程,当一个进程正在等待时,处理器可以转移到另一个进程,但是处理器比I/O 要快得多,以至于内存中所有的进程都在等待I/O 的情况很常见。
因此,即使是多道程序设计,大多数时候处理器仍然可能处于空闲状态。
一种解决方法是内存可以被扩充以适应更多的进程,但是这种方法有两个缺陷。
首先是内存的价格问题,当内存大小增加到兆位及千兆位时,价格也会随之增加;再者,程序对内存空间需求的增长速度比内存价格下降的速度快。
因此,更大的内存往往导致更大的进程,而不是更多的进程。
另一种解决方案是交换,包括把内存中某个进程的一部分或全部移到磁盘中。
当内存中没有处于就绪状态的进程时,操作系统就把被阻塞的进程换出到磁盘中的“挂起队列”(suspendqueue),这是暂时保存从内存中被“驱逐”出的进程队列,或者说是被挂起的进程队列。
操作系统在此之后取出挂起队列中的另一个进程,或者接受一个新进程的请求,将其纳入内存运行。
“交换”(swapping)是一个I/O 操作,因而也可能使问题更加恶化。
但是由于磁盘I/O 一般是系统中最快的I/O(相对于磁带或打印机I/O),所以交换通常会提高性能。
为使用前面描述的交换,在我们的进程行为模型(见图3.9a)中必须增加另一个状态:挂起态。
操作系统作业《模拟进程转换》
实验一进程状态模拟进程状态转换及其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);//重载<<
操作系统实验一模拟进程状态转换
实验一模拟进程状态转换及其PCB的变化一、实验目的:自行编制模拟程序,通过形象化的状态显示,使学生理解进程的概念、进程之间的状态转换及其所带来的PCB内容、组织的变化,理解进程与其PCB间的一一对应关系。
二、实验内容及要求:(1)、设计并实现一个模拟进程状态转换及其相应PCB内容、组织结构变化的程序。
(2)、独立编写、调试程序。
进程的数目、进程的状态模型(三状态、五状态、七状态或其它)以及PCB的组织形式可自行选择。
(3)、合理设计与进程PCB相对应的数据结构。
PCB的内容要涵盖进程的基本信息、控制信息、资源需求及现场信息。
(4)、设计出可视性较好的界面,应能反映出进程状态的变化引起的对应PCB内容、组织结构的变化。
(5)、代码书写要规范,要适当地加入注释。
(6)、鼓励在实验中加入新的观点或想法,并加以实现。
(7)、认真进行预习,完成预习报告。
(8)、实验完成后,要认真总结,完成实验报告。
三、实现:数据结构struct PCB{char name;int priority;int needtime;bool operator < (const PCB &b) const{ return priority>b.priority;}};五状态进程模型最高优先数优先调度算法流程图四、运行结果:图1 创建2个进程,因为这时cpu空闲所以内核调度,b优先级高先执行图2 超时,因为这时cpu空闲所以内核调度,b优先级还是比a高所以先执行图3 2个进程均被阻塞,其中一旦进程被阻塞就会引发调度图4 唤醒1个进程,从阻塞队列取队首放到就绪队列队尾,由于这时cpu空闲所以内核调度五、源代码:#include<cstdio>#include<algorithm>using namespace std;int Ready_len=0;int Blocked_len=0;int CPU_state=0;struct PCB{char name;int priority;int needtime;bool operator < (const PCB &b) const{ return priority>b.priority;}};PCB Ready[100];PCB Blocked[100];PCB Cpu;bool dispatch();bool creat(int NUM){//创建一个新的进程while(NUM--){printf("输入进程名(一个字符)、所需时间(一个整数)、优先级(一个整数): \n");scanf("%s%d%d",&(Ready[Ready_len].name),&(Ready[Ready_l en].needtime),&(Ready[Ready_len].priority));getchar();Ready_len++;}if(CPU_state==0)//如果CPU空闲,则调度dispatch();}bool dispatch(){if(CPU_state==0){if(Ready_len!=0){sort(Ready,Ready+Ready_len);=Ready[0].name;Cpu.needtime=Ready[0].needtime; Cpu.priority=Ready[0].priority;if(Ready_len!=1)//就绪队列剔除队首元素for(int indx=1;indx<Ready_len;indx++){Ready[indx-1].name=Ready[indx].name;Ready[indx-1].needti me=Ready[indx].needtime;Ready[indx-1].priority=Ready[indx] .priority;}Ready_len--;CPU_state=1;printf("***%c进程送往CPU执行\n",);Cpu.needtime--;Cpu.priority--;}else{printf("***就绪队列为空,无法调度\n");return false;}}else{printf("***CPU忙,无法调度\n");}}bool time_out(){if(CPU_state==1){if(Cpu.needtime==0)printf("***%c时间片用完,并且执行完毕,被释放\n",);else{Ready[Ready_len].name=;Ready[Ready_len].needti me=Cpu.needtime;Ready[Ready_len].priority=Cpu.priority;Ready_len++;printf("***%c时间片用完\n",);}CPU_state=0;=0;Cpu.needtime=0;Cpu.priority=0;if(Ready_len!=0)//时间片用完,如果就绪队列不为空,则调度dispatch();}else{printf("***没有进程在CPU中,无法超时\n");}}bool event_wait(){if(CPU_state==1){Blocked[Blocked_len].name=;Blocked[Blocked_le n].needtime=Cpu.needtime;Blocked[Blocked_len].priority=Cp u.priority;Blocked_len++;printf("***%c被阻塞\n",);CPU_state=0;if(Ready_len!=0)//进程被阻塞,如果就绪队列不为空,则调度dispatch();}elseprintf("***没有进程在CPU中,无法阻塞\n");}bool event_occur(){if(Blocked_len!=0){//sort(Blocked,Blocked+Blocked_len);Ready[Ready_len].name=Blocked[0].name;Ready[Ready_len].n eedtime=Blocked[0].needtime;Ready[Ready_len].priority=Bloc ked[0].priority;Ready_len++;if(Blocked_len!=1)//阻塞队列剔除队首元素for(int indx=1;indx<Blocked_len;indx++){Blocked[indx-1].name=Blocked[indx].name;Blocked[indx-1].ne edtime=Blocked[indx].needtime;Blocked[indx-1].priority=Bloc ked[indx].priority;}Blocked_len--;//printf("%d %d",Blocked_len,Ready_len);printf("***%c被唤醒\n",Ready[Ready_len-1].name);if(CPU_state==0)//如果CPU空闲,则调度dispatch();//printf("%d %d",Blocked_len,Ready_len);}elseprintf("***阻塞队列为空,无法唤醒\n");}int main(){int Cputime=1;while(1){printf("\n1:New\t\t\t2:Dispatch\n");printf("3:Timeout\t\t4:Event wait\n"); printf("5:Event occur\t\t0:exit\n");printf("输入1--5实现相应的功能:\n"); int select;scanf("%d",&select);getchar();switch(select){case 1:int num;printf("输入要创建的进程数:\n");scanf("%d",&num);getchar();creat(num);break;case 2:dispatch();break;case 3:time_out();break;case 4:event_wait();break;case 5:event_occur();break;case 0:exit(0);break;}printf("****************************Cputime:%3d************ ****************\n",Cputime);printf("状态\t\t进程名\t\t需要时间\t\t优先级\n");if(CPU_state){//显示CPU中的进程printf("Running:\t%c\t\t",);printf("%d\t\t\t",Cpu.needtime);printf("%d\n",Cpu.priority);}if(Ready_len){//显示Ready队列中的进程for(int a=0;a<Ready_len;a++){printf("Ready%d:\t\t",a);printf("%c\t\t",Ready[a].name);printf("%d\t\t\t",Ready[a].needtime);printf("%d\n",Ready[a].priority);}}if(Blocked_len){//显示Blocked队列中的程序for(int b=0;b<Blocked_len;b++){printf("Blocked%d:\t",b);printf("%c\t\t",Blocked[b].name);printf("%d\t\t\t",Blocked[b].needtime);printf("%d\n",Blocked[b].priority);}}printf("****************************************************** *************\n");Cputime++;}}。
操作系统实验(模拟进程管理)
操作系统实验————(1)模拟进程管理专业:信息管理与信息系统班级:信管082姓名:温静实验一进程管理1.目的和要求通过实验理解进程的概念,进程的组成(PCB结构),进程的并发执行和操作系统进行进程管理的相关原语(主要是进程的创建、执行、撤消)。
2.实验内容用C语言编程模拟进程管理,至少要有:创建新的进程;查看运行进程;换出某个进程;杀死运行进程以及进程之间通信等功能。
3.主体程序#include <conio.h>#include <stdio.h>#include <stdlib.h>struct PCB_type{ int pid;int priority;int cputime;int state;int shumu=0,pid_l;struct PCB_type neicun[20];struct PCB_type hc[10];int max=0;int number=0;void create();void run();void huanchu();void kill();/* 创建新进程*/void create(){if(shumu>=20){printf("\n内存已满,请先结束或换出进程\n");}else{shumu++;printf("\n请输入新进程的程序名\n");scanf("%d",&neicun[shumu-1].pid);printf("\n请输入新进程的优先级\n");scanf("%d",&neicun[shumu-1].priority);printf("\n请输入新进程的运行时间\n");scanf("%d",&neicun[shumu-1].cputime);printf("\n创建进程时令其状态为就绪\n");neicun[shumu-1].state=2;}printf("\n创建进程成功!\n");}/* 查看当前运行进程*/void run(){int max=0;for(int i=0;i<shumu;i++){if((neicun[i].state==1)&&(neicun[i].priority>=neicun[max].priority)) max=i;}neicun[max].state=3;printf("当前运行进程程序名:\n%d",neicun[max].pid);printf("\n该进程的优先级:\n%d",neicun[max].priority);printf("\n该进程的运行时间:\n%d",neicun[max].cputime);printf("\n该进程的状态:\n%d",neicun[max].state);}/* 换出*/void huanchu(){int k;printf("请输入要换出程序的程序名:");scanf("%d",&k);for(int j=0;j<shumu;j++){if(neicun[j].state==1){hc[number].pid=neicun[j].pid;hc[number].state=neicun[j].state;hc[number].priority=neicun[j].priority;hc[number].cputime=neicun[j].cputime;number++;neicun[j].pid=0;neicun[j].state=0;neicun[j].priority=0;neicun[j].cputime=0;pid_1++;}else printf("进程%d无法换出的pid:%d\n",j.neicun[j].pid);if(number!=0)for(int i=0;i<number;i++){printf("当前运行进程程序名:\n%d",hc[i].pid);printf("\n该进程的优先级:\n%d",hc[i].priority);printf("\n该进程的运行时间:\n%d",hc[i].cputime);printf("\n该进程的状态:\n%d",hc[i].state);}}PCB_type temp=neicun[0];for(k=0;k<=shumu;k++){if(neicun[k].priority>temp.priority)tmpe=neicun[k];}neicun[k].state=1;}/* 杀死进程*/void kill(){neicun[max].pid=0;neicun[max].priority=0;neicun[max].cputime=0;neicun[max].state=0;if(max==(shumu-1))shumu--;else{for(int j=max+1;j<shumu;j++){neicun[j-1].pid=neicun[j].pid;neicun[j-1].priority=neicun[j].priority;neicun[j-1].cputime=neicun[j].cputime;neicun[j-1].state=neicun[j].state;}shumu--;}max=0;run();}/* int k=0;printf("请输入要杀死程序的进程名:");scanf("%d",&k);if(neicun[k].state=1)neicun[k].state=2;neicun[k].cputime=0;neicun[k].pid=0;neicun[k].priority=0;neicun[k].state=0;if(k==(shumu-1))shumu--;else{for(int j=k+1;j<shumu;j++){neicun[j-1].pid=neicun[j].pid;neicun[j-1].priority=neicun[j].priority;neicun[j-1].cputime=neicun[j].cputime;neicun[j-1].state=neicun[j].state;}shumu--;}printf("进程%d已被杀死!,k");}*/int main(){int n,a;n=1;while(n==1){system("cls");printf("\n**********************************************");printf("\n* 进程演示系统*");printf("\n**********************************************");printf("\n 1.创建新的进程 2.查看运行进程");printf("\n 3.换出某个进程 4.杀死运行进程");printf("\n 5.退出系统");printf("\n**********************************************");printf("\n请选择(1~5):");scanf("%d",&a);switch(a){ case 1:create( );printf("\npress anykey to go on~");getch();break;case 2 :run();printf("\npress anykey to go on~");getch();break;case 3 :huanchu();printf("\npress anykey to go on~");getch();break;case 4 :kill();printf("\npress anykey to go on~");getch();break;case 5 :exit(0);default:n=0;break;}}}5.感想与心得体会做了两周的实验,问了很多同学,可程序还是有很多问题。
操作系统实验报告 实验一 进程管理
实验一进程管理一、目的进程调度是处理机管理的核心内容..本实验要求编写和调试一个简单的进程调度程序..通过本实验加深理解有关进程控制块、进程队列的概念;并体会和了解进程调度算法的具体实施办法..二、实验内容及要求1、设计进程控制块PCB的结构PCB结构通常包括以下信息:进程名进程ID、进程优先数、轮转时间片、进程所占用的CPU时间、进程的状态、当前队列指针等..可根据实验的不同;PCB结构的内容可以作适当的增删..为了便于处理;程序中的某进程运行时间以时间片为单位计算..各进程的轮转时间数以及进程需运行的时间片数的初始值均由用户给定..2、系统资源r1…r w;共有w类;每类数目为r1…r w..随机产生n进程P i 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为时间片大小毫秒//对进程进行初始化;建立就绪数组、阻塞数组..public void input//对进程进行初始化;建立就绪队列、阻塞队列{m = int.ParsetextBox4.Text;n = int.ParsetextBox5.Text;a = int.ParsetextBox6.Text;b = int.ParsetextBox7.Text;c = int.ParsetextBox8.Text;a1 = a;b1 = b;c1 = c;r = m - n;time1Inteval = int.ParsetextBox9.Text;timer1.Interval = time1Inteval;for i = 1; i <= n; i++{pcb jincheng = new pcb;jincheng.id = i;jincheng.ra = random.Nexta + 1;jincheng.rb = random.Nextb + 1;jincheng.rc = random.Nextc + 1;jincheng.ntime = random.Next1; 5;listBox1.Items.Add"产生进程ID:" + jincheng.id;listBox1.Items.Add"所需A资源数目:" + jincheng.ra;listBox1.Items.Add"所需B资源数目:" + jincheng.rb;listBox1.Items.Add"所需C资源数目:" + jincheng.rc;listBox1.Items.Add"所需时间片数:" + jincheng.ntime;if a - jincheng.ra >= 0 && b - jincheng.rb >= 0 && c - jincheng.rc >= 0{a = a - jincheng.ra;b = b - jincheng.rb;c = c - jincheng.rc;jincheng.state = 'W';hready.Addjincheng;//加入就绪队列}else{jincheng.state = 'B';hblock.Addjincheng;//加入阻塞队列}listBox1.Items.Add"当前进程状态:" + jincheng.state;}}//从数组起始地址开始输出该数组的内容public void dispArrayList list{ArrayList list1 = new ArrayList;list1 = list;if list1.Count > 0{for int j = 0; j < list1.Count; j++{pcb p = pcblist1j;listBox1.Items.Add" " + p.id.ToString + " " + p.state.ToString + " " + p.ra.ToString + " " + p.rb.ToString + " " + p.rc.ToString+" " + p.ntime.ToString + " " + p.rtime.ToString + " \r\n";}}else{listBox1.Items.Add"\r\n\t 该队列中没有进程\r\n";}}//输出就绪数组和阻塞数组的信息public void outputall{listBox1.Items.Add"当前就绪队列的信息";listBox1.Items.Add"进程ID 进程状态A资源数B资源数C资源数所需时间片已运行时间片";disphready;listBox1.Items.Add"当前就阻塞列的信息";listBox1.Items.Add"进程ID 进程状态A资源数B资源数C资源所需时间片已运行时间片";disphblock;}//运行就绪数组的头进程;运行一个时间片;轮转一个时间片;时间片轮转调度算法public void running{ArrayList hready1 = new ArrayList;hready1 = hready;pcb p1 = new pcb;p1=pcbhready10;p1.state='R';p1.rtime= p1.rtime + 1;h=h+1;listBox1.Items.Add"\r\n~~~~~~~当前正在运行进程ID是:" +p1.id + "~~~~~~~~\r\n";listBox1.Items.Add"\r\n进程ID 进程状态A资源数B资源数C资源数所需时间片已运行时间片\r\n";listBox1.Items.Addp1.id + " " +p1.state+ " " + p1.ra + " " + p1.rb + " " + p1.rc + " " + p1.ntime + " " + p1.rtime;if p1.ntime==p1.rtime{listBox1.Items.Addp1.id.ToString+"的进程已经完成\r\n";a = a + p1.ra;b = b + p1.rb;c = c + p1.rc;hready.RemoveAt0;}else{p1.state='W';hready1.Addp1;hready.RemoveAt0;}}//检测当前资源数目是否满足阻塞数组里进程的需求public void testblock{ArrayList hblock1 = new ArrayList;hblock1 = hblock;for int m = 0; m < hblock1.Count; m++{p1 = pcbhblock1m;if a - p1.ra >= 0 && b - p1.rb >= 0 && c - p1.rc >= 0{p1.state='W';hready.Addp1;a = a - p1.ra;b = b - p1.rb;c = c - p1.rc;listBox1.Items.Add"ID号为:"+p1.id + "的进程由阻塞队列转入就绪队列~~\r\n";hblock.RemoveAtm;m--;}}}//检测是否有新的进程产生;随机产生新进程public void testnew{int t;if r>0//r为随机产生的进程数目{t = random.Next9 + 1;if t <= 7{listBox1.Items.Add"\r\n有新的进程申请加入:~~";pcb jincheng = new pcb;jincheng.id = i++;jincheng.ra = random.Nexta + 1;jincheng.rb = random.Nextb + 1;jincheng.rc = random.Nextc + 1;jincheng.ntime = random.Next1; 5;jincheng.rtime = 0;listBox1.Items.Add"产生进程ID:" + jincheng.id;listBox1.Items.Add"所需A资源数目:" + jincheng.ra;listBox1.Items.Add"所需B资源数目:" + jincheng.rb;listBox1.Items.Add"所需C资源数目:" + jincheng.rc;listBox1.Items.Add"所需时间片数:" + jincheng.ntime;if a - jincheng.ra >= 0 && b - jincheng.rb >= 0 && c - jincheng.rc >= 0{a = a - jincheng.ra;b = b - jincheng.rb;c = c - jincheng.rc;jincheng.state = 'W';listBox1.Items.Add"进程状态为:" + jincheng.state;hready.Addjincheng;//加入就绪队列listBox1.Items.Add"资源满足新进程请求;该进程进入就绪队列~~\r\n";else{jincheng.state = 'B';hblock.Addjincheng;//加入阻塞队列listBox1.Items.Add"进程状态为:" + jincheng.state;listBox1.Items.Add"资源不满足新进程请求;该进程进入阻塞队列~~\r\n";}}}r = r - 1;}//系统三类资源变化情况的显示public void rescore//系统三类资源变化情况的显示{if a > a1 { textBox1.Text = a1.ToString; }if a < 0 { textBox1.Text = "0"; }if a >= 0 && a < a1 { textBox1.Text = a.ToString; }if b > b1 { textBox2.Text = b1.ToString; }if b < 0 { textBox2.Text = "0"; }if b >= 0 && b <= b1 { textBox2.Text = b.ToString; }if c > c1 { textBox3.Text = c1.ToString; }if c < 0 { textBox3.Text = "0"; }if c >= 0 && c <= c1 { textBox3.Text = c.ToString; }}//时间片轮转调度算法先来先服务FCFS算法public void runFcfs{if hready.Count>0{outputall;running;testblock;testnew;rescore;}else{timer1.Enabled = false;textBox1.Text = a1.ToString;textBox2.Text = b1.ToString;textBox3.Text = c1.ToString;listBox1.Items.Add"\r\n<<<<<<<<所有进程都已经运行结束>>>>>>>~\r\n";}//计时器触发时间片轮转调度算法private void timer1_Tickobject sender; EventArgs erunFcfs;}//开始模拟按钮单击执行函数private void button1_Clickobject sender; EventArgs e {runmain;button1.Enabled = false;textBox1.Enabled = false;textBox2.Enabled = false;textBox3.Enabled = false;textBox4.Enabled = false;textBox5.Enabled = false;textBox6.Enabled = false;textBox7.Enabled = false;textBox8.Enabled = false;textBox9.Enabled = false;}//清除屏幕按钮单击执行函数private void button2_Clickobject sender; EventArgs e {textBox1.Text = "";textBox2.Text = "";textBox3.Text = "";textBox4.Text = "";textBox5.Text = "";textBox6.Text = "";textBox7.Text = "";textBox8.Text = "";textBox9.Text = "";listBox1.Items.Clear;textBox4.Enabled = true;textBox5.Enabled = true;textBox6.Enabled = true;textBox7.Enabled = true;textBox8.Enabled = true;textBox9.Enabled = true;button1.Enabled = true;}//运行的主函数public void runmain{input;imer1.Enabled = true;3、运行界面和运行结果界面中;可以任意设定需要模拟的进程总数如5;初始化进程个数如3;还有A、B、C三类资源的总数如10、10、10..为了方便显示;还可以设定时间片的长度如500毫秒..除此之外;在运行过程中;所有的资源都是随机生成的;并且其中新进程的产生也是随机的;但是产生的进程总数不会多于开始设定的模拟的进程总数;以防止不断产生新进程;程序不断运行..在显示窗口的上方;还会实时显示资源的变化情况;方便对运行的观察..当运行结束后;可以通过工具栏中的显示选项中的保存结果按钮;将结果保存成txt文件格式;方便运行后的结果分析..五、心得体会本次实验;我的任务是设计一个允许n个进程并发运行的进程管理模拟系统..该系统包括有简单的进程控制、同步与通讯机构;系统在运行过程中能显示各进程的状态及有关参数的变化情况;从而观察诸进程的运行过程及系统的管理过程;我是用C写的;在我的电脑能够运行通过;虽不能尽善尽美;但也基本能实现老师的要求..两个星期的实验;虽然时间有点短;但我也收获不少;这次实验;加深了我对进程概念及进程管理的理解;比较熟悉进程管理中主要数据结构的设计及进程调度算法、进程控制机构、同步机构及通讯机构的实施..也让我认识到自己的不足;操作系统的有些知识;我知道的还不多;没有掌握好;还需要多多学学;不断提升自己的能力..实验中;我们小组分工合作;共同学习;虽然在实验中遇到了一些问题;但在老师和同学的细心指导和热心帮助下解决了..同时;了解到团队精神的重要性;也为以后的学习和工作打下了坚实的基础;同时积累了宝贵的经验..。
操作系统实验进程状态转换及其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)就绪状态(Ready)。
这是指进程已处于准备好运⾏的状态,即进程已分配到除cpu以外的所有必要资源后,只要获得cpu,便可⽴即执⾏。
如果系统中有许多处于就绪状态的进程,通常将它们按⼀定的策略(如优先级策略)排成⼀个队列,称该队列为就绪队列。
(2)执⾏状态(Running)。
这是指进程已获得cpu,其程序正在执⾏的状态。
对任何⼀个时刻⽽⾔,在单处理机系统中,只有⼀个进程处于执⾏状态,⽽在多处理机系统中,则有多个进程处于执⾏状态。
(3)阻塞状态(BLOCK)。
这是指正在执⾏的进程由于发⽣某事件(如I/O请求、申请缓冲区失败等)暂时⽆法继续执⾏时的状态,亦即进程的执⾏受到阻塞。
此时引起进程调
度,OS把处理机分配给另⼀个就绪进程,⽽让受阻进程处于暂停状态,⼀般把这种暂停状态称为阻塞状态,有时也称为等待状态或封锁状态。
通常系统将处于阻塞状态的进程也排成⼀个队列,称该队列为阻塞队列。
实际上,在较⼤的系统中,为了减少队列操作的开销,提⾼系统效率,根据阻塞原因的不同,会设置多个阻塞队列。
如下,为进程的三种状态的转换
1.处于就绪状态的进程,在调度程序为之分配了处理机之后便可执⾏,相应地,其状态就由就绪态变为运⾏态;
2.正在执⾏的进程(当前进程)如果因为分配给它的时间⽚已完⽽被剥夺处理机暂停执⾏时,其状态就由执⾏态转为就绪;
3.如果因为某事件,致使当前进程的执⾏受阻(例如进程访问某临界资源,⽽该资源正被其他进程访问时),使之⽆法继续执⾏,则该进程状态由执⾏转为阻塞。
进程的三种状态转换
进程的三种状态转换实验报告实验名称进程的三种状态转换专业计算机科学与技术课程名称操作系统指导老师张海燕老师班级 2011级二表1班姓名姜玉龙学号 ********** 评分实验地点 1c26217 实验日期 2013/09/18一、实验目的1.熟悉进程管理及其相关的基本概念。
2.通过实验掌握进程的三种转化,执行,就绪,阻塞及其相关知识。
二、实验内容(含实验原理介绍)1. 就绪状态:当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态。
2(执行状态 :当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态。
3.阻塞)状态 :正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。
引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等三、实验过程及步骤(包含使用软件或实验设备等情况)实验设备:装有vc++6.0的pc实验步骤:创建链表 LinkList CreateListR(int Num)LinkList head = (LinkList)malloc(sizeof(ListNode))s=(ListNode *)malloc(sizeof(ListNode))返回key结点位置LinkList LocateNode(LinkList head,DataType key) {while (head->data != key && head)head=head->next;return head;}删除进程LinkList LocateNode(LinkList head,DataType key)while (head->data != key && head)head=head->nextreturn head显示链表void ShowList(LinkList head)head = head->next;在链表中删除结点key void ClearList(LinkList head,DataType key) 删除链表void DeleteList(LinkList head) {head=p->next;free(p);p=head;}创建链表向就绪状态转化void FreeToReady(LinkList FreeP,LinkList ReadyP,DataType key){p=FreeP->next;FreeP->next=p->next;p->data=key;q=ReadyP;while(q->next)q=q->next;q->next=p;p->next=NULL;}就绪状态向执行状态转化void ReadyToExe(LinkList ReadyP,LinkList ExeP,DataType key){ExeP->next=LocateNode(ReadyP,key);ClearList(ReadyP,key);ExeP->next->next=NULL;printf("Execute process %c success.\n",key);}执行状态向就绪状态转化void ExeToReady(LinkList ExeP,LinkList ReadyP) p=p->next;p->next=ExeP->next;ExeP->next=NULL;阻塞状态向就绪状态转化void BlockToReady(LinkList BlockP,LinkList ReadyP,DataType key){ LinkList p,q;p=LocateNode(BlockP,key);q=ReadyP;while(q->next)q=q->next;q->next=p;ClearList(BlockP,key);p->next=NULL; }执行状态向阻塞状态转化void ExeToBlock(LinkList ExeP,LinkList BlockP) {LinkList p;p=BlockP;while(p->next)p=p->next;p->next=ExeP->next;ExeP->next=NULL;int main(){ ...cmd=getchar();switch(cmd){ case 'c': //创建进程while(LocateNode(ReadyP,Name)||LocateNode(BlockP,Name) ||LocateNode(ExeP,Name))Name=Name+1;if((LocateNode(ReadyP,Name) || LocateNode(ExeP,Name) ||LocateNode(BlockP,Name)) == NULL)FreeToReady(FreeP,ReadyP,Name);case 'P': //输入进程名if(LocateNode(ReadyP,Name))ReadyToExe(ReadyP,ExeP,Name);case 'E': //结束进程while(temp->next)temp=temp->next;temp->next=ExeP->next;ExeP->next=NULL;printf("End process %c success.\n",temp->next->data);case 'B': //清空进程if(ExeP->next)printf("Block process %c success.\n",ExeP->next->data); elseprintf("Error: No process executing.\n");case 'w': //唤醒进程 Name=getchar();getchar();if(LocateNode(BlockP,Name))printf("Wakeup process %c success.\n",Name);}... }四、实验结果(含算法说明、程序、数据记录及分析等,可附页)五、实验思考题进程状态转换中,存在四种状态转换。
进程切换实验报告
一、实验目的通过本次实验,了解进程切换的基本概念和过程,掌握进程切换的触发条件、切换过程以及切换开销,加深对进程调度和管理的理解。
二、实验环境操作系统: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)。
实验一模拟进程状态转换及其PCB的变化一、实验目的:
自行编制模拟程序,通过形象化的状态显示,使学生理解进程的概念、进程之间的状态转换及其所带来的PCB内容、组织的变化,理解进程与其PCB间的一一对应关系。
二、实验内容及要求:
(1)、设计并实现一个模拟进程状态转换及其相应PCB内容、组织结构变化的程序。
(2)、独立编写、调试程序。
进程的数目、进程的状态模型(三状态、五状态、七状态或其它)以及PCB的组织形式可自行选择。
(3)、合理设计与进程PCB相对应的数据结构。
PCB的内容要涵盖进程的基本信息、控制信息、资源需求及现场信息。
(4)、设计出可视性较好的界面,应能反映出进程状态的变化引起的对应PCB内容、组织结构的变化。
(5)、代码书写要规范,要适当地加入注释。
(6)、鼓励在实验中加入新的观点或想法,并加以实现。
(7)、认真进行预习,完成预习报告。
(8)、实验完成后,要认真总结,完成实验报告。
三、实现:
数据结构
struct PCB{
char name;
int priority;
int needtime;
bool operator < (const PCB &b) const{ return priority>;
}
};
五状态进程模型
最高优先数优先调度算法流程图
四、运行结果:
图1 创建2个进程,因为这时cpu空闲所以内核调度,b优先级高先执行
图2 超时,因为这时cpu空闲所以内核调度,b优先级还是比a高所以先执行
图3 2个进程均被阻塞,其中一旦进程被阻塞就会引发调度
图4 唤醒1个进程,从阻塞队列取队首放到就绪队列队尾,由于这时cpu空闲所以内核调
度
五、源代码:
#include<cstdio>
#include<algorithm>
using namespace std;
int Ready_len=0;
int Blocked_len=0;
int CPU_state=0;
struct PCB{
char name;
int priority;
int needtime;
bool operator < (const PCB &b) const{
return priority>;
}
};
PCB Ready[100];
PCB Blocked[100];
PCB Cpu;
bool dispatch();
bool creat(int NUM){ame),&(Ready[Ready_len].needtime),&(Ready[Ready_len].prior ity));getchar();
Ready_len++;
}
if(CPU_state==0)ame;=Ready[0].needtime;=Ready[0].priority;
if(Ready_len!=1)ame=Ready[indx].name;Ready[indx-1].needtime=Ready[indx].needtime;Ready[indx-
1].priority=Ready[indx].priority;
}
Ready_len--;
CPU_state=1;
printf("***%c进程送往CPU执行\n",;
;
;
}else{
printf("***就绪队列为空,无法调度\n");
return false;
}
}else{
printf("***CPU忙,无法调度\n");
}
}
bool time_out(){
if(CPU_state==1){
if==0)
printf("***%c时间片用完,并且执行完毕,被释放\n",;
else{
Ready[Ready_len].name=;Ready[Ready_len].needtime=;Ready[Ready _len].priority=;
Ready_len++;
printf("***%c时间片用完\n",;
}
CPU_state=0;
=0;
=0;
=0;
if(Ready_len!=0)ame=;Blocked[Blocked_len].needtime=;Blocked[Bloc ked_len].priority=;
Blocked_len++;
printf("***%c被阻塞\n",;
CPU_state=0;
if(Ready_len!=0)ame=Blocked[0].name;Ready[Ready_len].needtime=
Blocked[0].needtime;Ready[Ready_len].priority=Blocked[0].priority;
Ready_len++;
if(Blocked_len!=1)ame=Blocked[indx].name;Blocked[indx-1].needtime=Blocked[indx].needtime;Blocked[indx-
1].priority=Blocked[indx].priority;
}
Blocked_len--;
ame);
if(CPU_state==0)ame);
printf("%d\t\t\t",Ready[a].needtime);
printf("%d\n",Ready[a].priority);
}
}
if(Blocked_len){ame);
printf("%d\t\t\t",Blocked[b].needtime);
printf("%d\n",Blocked[b].priority);
}
}
printf("************************************************************* ******\n");
Cputime++;
} }。