操作系统实验一练习进程状态转换
操作系统实验报告进程状态转换
实验进程状态转换及其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(); // 调用进程运行函数}四、运行结果及说明:运行结果的截图:下面的运行结果是程序执行的每一步进程调度的显示,从进程的创建到进程的执行,结束,每一步进程调度都有显示。
实验一、进程调度实验报告
实验一、进程调度实验报告一、实验目的进程调度是操作系统中的核心功能之一,其目的是合理地分配 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
1.某系统的进程状态转换图如图,请说明1)引起各种状态转换的典型事件有哪些?2)当我们观察系统中某些进程时,能够看到某一进程产生的一次状态转换能引起另一进程作一次状态转换。
在什么情况下,当一个进程发生转换3时能立即引起另一进程发生转换1。
3)试说明是否会发生下述因果转换:2→1 3→2 4→12.设有n各进程共享一个程序段,对如下两种情况:1)如果每次只允许一个进程进入该程序段2)如果每次最多允许m(m<n)个进程同时进入该程序段试问:所采用的信号量初值是否相同?信号量值的变化范围如何?3.设有一个计算进程PUT和两个取数进程GUT1和GUT2,进程PUT不断地把计算得到的结果(整数)送入变量buf,如果送入buf的数是奇数,应由GUT1取出并打印。
如果送入buf的数是偶数,应由GUT2取出并打印。
要求:即不漏打,也不重复打印。
请用P、V操作,并用类PASCAL或类C或流程图,描述对应与各进程的程序。
4.有一个仓库可以存放A、B两种物品,每次只能存入一件物品(A或B)。
存储空间充分大,只是要求:-N<A的件数-B的件数<M,其中N和M 是正整数。
试用P、V操作描述物品A和物品B的入库过程,且要求定义出所需信号量及其初始值。
5.一台计算机有8台磁带机,它们由N个进程竞争使用,每个进程可能需要3台磁带机,请问N为多少时,系统没有死锁危险,并说明理由。
6.假定某计算机系统有R1和R2两类可使用资源(其中R1有两个单位,R2有一个单位。
他们被进程P1和P2共享,且已知两个进程均以下列顺序是用两类资源:→申请R1→申请R2→申请R1→释放R1→释放R2→释放R1→试求出系统运行过程中可能到达的死锁点,并画出死锁点的资源分配图。
7.某系统由R1、R2和R3三种资源,在T0时刻P1,P2,P3,P4四个进程对资2,1,2),问题:1)将系统中各种资源总数和此刻个进程对资源的需求数目用向量或矩阵表示出来。
操作系统实验一模拟进程状态转换
操作系统实验一模拟进程状态转换四、运行结果:图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++;} }。
操作系统进程的三种状态的转换实验报告
3.设计出可视性较好的界面,应能反映出进程状态的变化引起的对应内容。
4.代码书写要规范,要适当地加入注释。
5.编译并调试自己编写的程序,是程序编译成功。
6.检查运行的结果是否正确。
四、实验结果(含算法说明、程序、数据记录及分析等,可附页)
五、实验思考题
利用C语言编写了一个模拟Windows进程三种状态之间的转换的程序,虽然肥城精简,但是我从中学到的很多知识点,学会了编写程序时的一些技巧,为自己以后更加深造打下了坚实的基础和使自己更好的理解Windows如何更好的管理进程。
六、实验总结(含实验心得体会,收获与不足等)
通过这次实验让我受益匪浅,不仅明白了自己以前不知道如何定义和应用结构体,还提高了自己的编程能力,调试程序的能力,使自己的编程能力有了大幅度的提高。使自己更好的理解进程的概念和进程的三种状态之间转换的过程和他们之间的关系。为自己以后复习打下了夯实的基础。
1)根据课本第三章的内容设计并实现一个模拟进程状态转换。
2)独立编写和调试程序。进程的数目,进程的状态模型自行选择。
3)合理设计进程相对应的数据结构,内容要包括进程的基本信息。
4)是进程的三种状态之间的转化清晰的显示。
三、实验过程及步骤(包含使用软件或实验设备等情况)
1.打开DEV-C++,新建一个源代码文件
实验报告
实验名称
进程三种状态的转换
专业
计算机
课程名称
操作系统
指导老师
张海燕
班级
二表一班
姓名
刘广法
学号
11100140109
评分
实验地点
1cபைடு நூலகம்6217
操作系统实验一练习进程状态转换
实验一模拟进程状态转换及其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高所以先执行图32个进程均被阻塞,其中一旦进程被阻塞就会引发调度图4唤醒1个进程,从阻塞队列取队首放到就绪队列队尾,由于这时cpu空闲所以内核调度五、源代码:#include<cstdio>#include<algorithm>using namespace std。
int Ready_len=0。
int Blocked_len=0。
int CPU_state=0。
国家开放大学《操作系统》形考任务(应用题)参考答案
国家开放大学《操作系统》形考任务(应用题)参考答案1. 用如图所示的进程状态转换图能够说明有关处理机管理的大量内容。
图进程状态转换图试回答:①什么事件引起每次显著的状态变迁?②下述状态变迁因果关系能否发生?为什么?参考答案:①就绪→运行:CPU 空闲,就绪态进程被调度程序选中。
运行→就绪:正在运行的进程用完了本次分配给它的CPU 时间片。
运行 → 阻塞:运行态进程因某种条件未满足而放弃对CPU 的占用,如等待读文件。
阻塞→就绪:阻塞态进程所等待的事件发生了,例如读数据的操作完成。
②下述状态变迁:(A)2 → 1:可以。
运行进程用完了本次分配给它的时间片,让出CPU,从 就绪队列中选一个进程投入运行。
(B)3 →2:不可以。
任何时候一个进程只能处于一种状态,它既然由运行 态变为阻塞态,就不能再由运行态变为就绪态。
(C)4 → 1:可以。
某一阻塞态进程等待的事件出现了,而且此时就绪队列 运行状态1/24 阻塞状态就绪 状态 3为空,该进程进入就绪队列后马上又被调度运行。
2.系统中只有一台打印机,有三个用户的程序在执行过程中都要使用打印机输出计算结果。
设每个用户程序对应一个进程。
问:这三个进程间有什么样的制约关系?试用P、v操作写出这些进程使用打印机的算法。
参考答案:因为打印机是一种临界资源,所以这三个进程只能互斥使用这台打印机,即一个用户的计算结果打印完之后,另一个用户再打印。
设三个进程分别为A、B和C。
设一个互斥信号量mutex,其初值为1。
进程A 进程B 进程CP(mutex) 使用打印机V(mutex)P(mutex)使用打印机V(mutex)P(mutex)使用打印机V(mutex)3. 判断下列同步问题的算法是否正确?若有错,请指出错误原因并予以改正。
①设A,B两个进程共用一个缓冲区Q,A向Q写入信息,B从Q读出信息,算法框图如图左侧所示。
②设A,B为两个并发进程,它们共享一个临界资源。
操作系统--进程状态切换以及cpu调度(转)
操作系统--进程状态切换以及cpu调度(转)进程的状态转换 进程在运⾏中不断地改变其运⾏状态。
通常,⼀个运⾏进程必须具有以下三种基本状态。
进程状态执⾏态run:进程正在使⽤CPU等待态wait:进程正在等待I/O完成,不在使⽤也不能使⽤CPU就绪态ready:进程不在使⽤CPU,但已经纯备好⽤使⽤CPU 在特定的情况下,这三种状态可以相互转换。
状态转换 就绪->执⾏,当前运⾏进程阻塞,调度程序选⼀个优先权最⾼的进程占有处理机; 执⾏->就绪,当前运⾏进程时间⽚⽤完; 执⾏->等待,当前运⾏进程等待键盘输⼊,进⼊了睡眠状态。
等待->就绪,I/O操作完成,被中断处理程序唤醒。
刚从其他状态进⼊就绪态的进程需要置⼊调度队列,该队列不⼀定按进⼊队列的时间先后顺序排列。
从等待态中出来的进程通常不直接进⼊运⾏态,⽽要进⼊就绪态。
如果需要直接进⼊运⾏态,这属于抢先式调度,通过抢先式中断完成。
从执⾏态到就绪态的转换发⽣在抢先式终端处理中,例如I/O或分时下的时间⽚。
分时是在多个⽤户同时以交互⽅式使⽤计算机时采⽤的⼀种技术。
分时技术:每当时钟中断发⽣时且发现当前运⾏进程已连续在CPU上运⾏了⼀定的时间(称为时间⽚,⼀般为20ms~250ms)时,就强制地发⽣进程切换,使当前进程退出CPU,重新调度,选出另⼀个进程在CPU上运⾏。
此时,退出的进程不能变为等待状态,因为它不是因为等待I/O⽽退出的,也不能变为终⽌,因为它尚未结束,因此,它需要转换为就绪态,等待属于它的时间⽚的到来。
当正在建⽴⼀个新进程时,计算机上的当前运⾏进程是哪⼀个? 该新进程的⽗进程。
CPU调度算法 同时处于就绪态的进程经常有多个,因此需要⼀个CPU调度算法来君顶那⼀个就绪进程先运⾏。
衡量CPU调度算法的标准有:CPU利⽤率、⽤户程序响应时间、系统吞吐量、公平合理性、设备利⽤率等。
常见的调度算法有先来先服务FIFO、轮转调度法RR(时间⽚法)、优先级调度法、短作业优先SJF、最短剩余事件优先、最⾼相应⽐优先、多级反馈法、策略驱动法、最晚时间限调度、⼆级调度法。
操作系统-进程的状态与转换
操作系统-进程的状态与转换进程的状态与转换状态进程是程序的⼀次执⾏。
在这个执⾏过程中,有时进程正在被CPU处理,有时⼜需要等待CPU服务,可见,进程的状态是会有各种变化。
为了⽅便对各个进程的管理,操作系统需要将进程合理地划分为⼏种状态。
三种基本状态运⾏态(Running)CPU√ 其他所需资源×占有CPU,并在CPU上运⾏注意:单核处理机环境下,每⼀时刻最多只有⼀个进程处于运⾏态。
(双核环境下可以同时有两个进程处于运⾏态)。
就绪态(Ready)CPU√ 其他所需资源×已经具备运⾏条件,但由于没有空闲CPU,⽽暂时不能运⾏进程已经拥有了除了处理机之外所有需要地资源,⼀旦获得处理机,即可⽴即进⼊运⾏态开始运⾏。
即:万事俱备,只⽋CPU。
阻塞态(Waiting/Blocked,⼜称等待态)CPU× 其他所需资源×因等待某⼀事件⽽暂时不能运⾏如:等待操作系统分配打印机,等待读磁盘操作地结果。
CPU是计算机中最昂贵地部件,为了提⾼CPU地利⽤率,需要先将其他进程需要地资源分配到位,才能得到CPU的服务。
另外两种状态创建态(New,⼜名:新建态)进程正在被创建,操作系统为进程分配资源、初始化PCB。
终⽌态(Terminated,⼜称:结束态)进程正在从系统中撤销,操作系统会回收进程拥有的资源。
进程状态的转换图⽚来⾃王道考研B站视频截图就绪态=>运⾏态进程被调度运⾏态=>就绪态时间⽚到,或CPU被其他⾼优先级的进程抢占运⾏态=>阻塞态等待系统资源分配,或等待某事件发⽣(主动⾏为)阻塞态=>就绪态资源分配到位,等待事件的发⽣(被动⾏为)⼏个注意点运⾏态=>阻塞态是⼀种进程⾃⾝作出的主动⾏为阻塞态=>就绪态不是进程⾃⾝能控制的,是⼀种被动⾏为不能由阻塞态直接转换为运⾏态,也不能由就绪态直接转换为阻塞态(因为进⼊阻塞态是进程主动请求的,必然需要进程在运⾏时才能发出这种请求)。
进程状态转换
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的变化
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变化的影响。
实验结果分析
现代操作系统课后习题答案
第二章进程管理第一部分教材习题(P81)3、为什么程序并发执行会产生间断性特征?(P36)4、程序并发执行,为何会失去封闭性和可再现性?(P37)【解】程序在并发执行时,是多个程序共享系统中的各种资源,因而这些资源的状态将由多个程序来改变,致使程序的运行已失去了封闭性。
同时由于失去了封闭性,也将导致其再失去可再现性。
程序在并发执行时,由于失去了封闭性,程序经过多次执行后,其计算机结果已与并发程序的执行速度有关,从而使程序的执行失去了可再现性。
5、在操作系统中为什么要引入进程概念?(P37)它会产生什么样的影响?【解】在操作系统中引入进程的概念,是为了实现多个程序的并发执行。
传统的程序不能与其他程序并发执行,只有在为之创建进程后,才能与其他程序(进程)并发执行。
这是因为并发执行的程序(即进程)是“停停走走”地执行,只有在为它创建进程后,在它停下时,方能将其现场信息保存在它的PCB中,待下次被调度执行是,再从PCB中恢复CPU现场并继续执行,而传统的程序却无法满足上述要求。
建立进程所带来的好处是使多个程序能并发执行,这极大地提高了资源利用率和系统吞吐量。
但管理进程也需付出一定的代价,包括进程控制块及协调各运行机构所占用的内存空间开销,以及为进行进程间的切换、同步及通信等所付出的时间开销。
6、试从动态性、并发性和独立性上比较进程和程序?(P37)【解】(1)动态性:进程既然是进程实体的执行过程,因此,动态性是进程最基本的特性。
动态性还表现为:“它由创建而产生,由调度而执行,因得不到资源而暂停执行,以及由撤消而消亡”。
可见,进程有一定的生命期。
而程序只是一组有序指令的集合,并存放在某种介质上,本身并无运动的含义,因此,程序是个静态实体。
(2)并发性:所谓进程的并发,指的是多个进程实体,同存于内存中,能在一段时间内同时运行。
并发性是进程的重要特征,同时也成为OS的重要特征。
引入进程的目的也正是为了使其程序能和其它进程的程序并发执行,而程序是无法并发执行的。
进程的三种状态转换
进程的三种状态转换实验报告实验名称进程的三种状态转换专业计算机科学与技术课程名称操作系统指导老师张海燕老师班级 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);}... }四、实验结果(含算法说明、程序、数据记录及分析等,可附页)五、实验思考题进程状态转换中,存在四种状态转换。
操作系统之进程转换
2. 某系统的进程状态转换如图所示,请说明:1引起各种状态转换的典型事件有哪些?2当我们观察系统中某些进程时,能够看到某一进程产生的一次状态转换能引起另一个进程作一次状态转换。
在什么情况下,当一个进程发生转换3时能立即引起另一个进程发生转换1;3试说明是否会发生下述因果转换:2→13→24→1解答:4在本题所给的进程状态转换图中,存在四种状态转换。
当进程调度程序从就绪队列中选取一个进程投入运行时引起转换1;正在执行的进程如因时间片用完而被暂停执行就会引起转换2;正在执行的进程因等待的事件尚未发生而无法执行(如进程请求完成I/O)则会引去转换3;当进程等待的事件发生时(如I/O完成)则会引起转换4。
5如果就绪队列非空,则一个进程的转换3会立即引去另一个进程的转换1。
这是因为一个进程发生转换3意味着正在执行的进程由执行状态变为阻塞状态,这时处理机空闲,进程调度程序必然会从就绪队列中选取一个进程并将它投入运行,因此只要就绪队列非空,一个进程的转换3能立即引起一个进程的转换1。
6所谓因果转换指的是有两个转换,一个转换的发生会引起另一个转换的发生,前一个转换称为因,后一个转换成为果,这两个转换称为因果转换。
当然这种因果关系并不是什么时候都能发生,而是在一定条件下才能发生。
2→1:当某进程发生转换2时,就必然引起另一个进程的转换1。
因为当发生转换2时,正在执行的进程从执行状态变为就绪状态,进程调度程序必然会从就绪队列中选取一个进程投入运行,即发生转换1。
3→2:某一进程的转换3决不可能引起另一个进程发生转换2。
这是因为当前执行进程从执行状态变为阻塞状态,不可能又从执行状态变为就绪状态。
4→1:当处理机空闲且就绪队列为空时,某一进程的转换4就会引起该进程的转换1。
因为此时处理机空闲,一旦某个进程发生转换4,就意味着有一个进程从阻塞状态变为就绪状态,因而调度程序就会将就绪队列中的此进程投入运行。
一、进程的三种基本状态进程在运行中不断地改变其运行状态。
进程切换实验报告
一、实验目的通过本次实验,了解进程切换的基本概念和过程,掌握进程切换的触发条件、切换过程以及切换开销,加深对进程调度和管理的理解。
二、实验环境操作系统: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()函数使进程休眠一段时间。
操作系统作业
模拟进程状态的转换作业内容:进程的3个基本状态:执行、就绪、等待,其转换标识分别为1、2、3、4(如图)。
编程模拟进程状态转换过程,要求:分别建立等待队列和就绪队列(单队列、结构不限),初始状态时,1个进程处于执行状态,7个进程在等待队列中,7个进程在就绪队列中。
手工触发任意一种转换,显示转换发生后的执行进程和两个队列的进程。
程序流程图:开始初始化等待和阻塞队列等得队列首个进程进入运行队列显示所有队列信息是否阻塞?正在执行进程进入阻塞队列是运行进程消耗一个时间片否阻塞队列首位所需条件是否满足阻塞队列首个进程进入等待队列是运行进程是否结束运行队列清空是运行进程进入等待队列否等待队列为空?否结束是否说明(1)上为运行结果,x<y>:x为进程号;y为进程结束剩余时间片。
(2)程序中使用队列数据结构,并以结构体process(进程)作为队列元素。
(3)程序自动进行时间片分配,但每次运行一个进程前需要进行阻塞判断,手动输入。
#include<iostream>#include<queue>#include<windows.h>using namespace std;struct process{int id;int rt;process(){}process(int a,int b){id=a;rt=b;}};queue<process> re,bl,ru;int main(){void show(queue<process> re,queue<process> ru,queue<process> bl);processp1(1,2),p2(2,1),p3(3,1),p4(4,3),p5(5,2),p6(6,1),p7(7,2),p8(8,1),p9(9,1),p10(10,3),p11(11,2),p12(1 2,1),p13(13,3),p14(14,2),p15(15,1);ru.push(p1);re.push(p2);re.push(p3);re.push(p4);re.push(p5);re.push(p6);re.push(p7);re.push(p8);bl.push(p9);bl.push(p10);bl.push(p11);bl.push(p12);bl.push(p13);bl.push(p14);bl.push(p15);process x;char ch;int n;cout<<"初始化中.";cout<<"."<<endl<<endl;show(re,ru,bl);cout<<endl<<"开始执行!"<<endl<<endl; while(!re.empty()){cout<<endl<<"是否阻塞?(y/n)"<<endl;ch=getchar();getchar();if(ch=='y'){x=ru.front();ru.pop();bl.push(x);x=re.front();re.pop();ru.push(x);show(re,ru,bl);}else if(ch=='n'){x.rt--;ru.front().rt=x.rt;if(x.rt!=0){x=ru.front();ru.pop();re.push(x);}else ru.pop();x=re.front();re.pop();ru.push(x);show(re,ru,bl);}else cout<<"输入有误"<<endl;if(!bl.empty()){x=bl.front();cout<<endl<<"进程"<<x.id<<"要求是否满足?(y/n)"<<endl;ch=getchar();getchar();if(ch=='y'){x=bl.front();bl.pop();re.push(x);show(re,ru,bl);}else if(ch=='n'){cout<<endl;}else cout<<"输入有误"<<endl;}}return 0;}void show(queue<process> re,queue<process> ru,queue<process> bl){cout<<"运行任务:";process y;if(ru.empty())cout<<"空"<<endl;else{y=ru.front();ru.pop();cout<<y.id<<"("<<y.rt<<")"<<endl;}cout<<"就绪中的任务:";if(!re.empty()){while(!re.empty()){y=re.front();re.pop();cout<<y.id<<"("<<y.rt<<") ";}}else cout<<"空";cout<<endl<<"阻塞中的任务:";if(!bl.empty()){while(!bl.empty()){y=bl.front();bl.pop();cout<<y.id<<"("<<y.rt<<") ";}}else cout<<"空";cout<<endl;}。
操作系统进程状态转换考试题
操作系统进程状态转换考试题一、在操作系统中,当一个进程从就绪状态转变为运行状态,这通常意味着什么?A. 进程已被加载到内存中B. 进程已获得CPU的控制权C. 进程正在等待I/O操作完成D. 进程已被阻塞等待某个事件(答案:B)二、以下哪种情况会导致进程从运行状态转变为阻塞状态?A. 进程执行完所有任务B. 进程需要等待某个资源或事件C. 进程被操作系统调度器选中执行D. 进程主动放弃CPU(答案:B)三、当一个进程完成其执行并释放所有资源时,它将进入哪种状态?A. 就绪状态B. 运行状态C. 阻塞状态D. 终止状态(答案:D)四、在操作系统中,进程的挂起状态与哪种状态相似,但有所不同?A. 就绪状态,因为两者都等待CPUB. 运行状态,因为两者都占用系统资源C. 阻塞状态,因为两者都等待事件D. 终止状态,因为两者都不再执行(答案:A)五、进程从阻塞状态恢复到就绪状态通常是因为?A. 进程被强制终止B. 进程等待的事件已经发生C. 操作系统需要重新调度D. 进程执行了非法操作(答案:B)六、以下哪个操作可能导致进程从就绪状态转变为运行状态?A. 进程请求I/O操作B. 进程被调度器选中执行C. 进程遇到不可恢复的错误D. 进程主动进入睡眠状态(答案:B)七、在操作系统中,当多个进程竞争同一个资源时,可能会导致某些进程进入哪种状态?A. 运行状态B. 就绪状态C. 阻塞状态,等待资源可用D. 挂起状态(答案:C)八、当一个进程由于等待某种条件(如I/O完成)而主动放弃CPU时,它将进入哪种状态?A. 运行状态,因为它仍然在执行B. 就绪状态,因为它准备再次执行C. 阻塞状态,因为它正在等待条件满足D. 挂起状态,因为它被移出内存(答案:C)。
- 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>b.priority。
}}。
五状态进程模型最高优先数优先调度算法流程图四、运行结果:图1创建2个进程,因为这时cpu空闲所以内核调度,b优先级高先执行图2超时,因为这时cpu空闲所以内核调度,b优先级还是比a高所以先执行图32个进程均被阻塞,其中一旦进程被阻塞就会引发调度图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].needtime=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].needtime=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].needtime=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)。