操作系统实验 进程状态转换及其PCB的变化
计算机操作系统慕课版pcb概念

计算机操作系统慕课版pcb概念PCB (Process Control Block)是计算机操作系统中的一个重要概念,也被称为进程控制块。
PCB 存储了操作系统管理和控制进程所需的所有信息。
每个进程都对应一个 PCB,当操作系统创建进程时,会为其分配一个 PCB,并将其放入一个进程队列中。
PCB 中包含的信息可以分为几个部分:1. 进程状态:记录当前进程的状态,如就绪、运行、阻塞等。
2. CPU 寄存器:保存了当前进程的程序计数器、堆栈指针和其他寄存器的值。
3. 进程标识符:唯一地标识一个进程,通常由一个进程ID来表示。
4. 进程优先级:用于定义进程的优先级,以确定进程在调度时的权重。
5. 程序计数器:记录了进程当前执行的指令地址。
6. 内存管理信息:包括进程所占用的内存地址范围、页表等。
7. 文件描述符表:保存了该进程打开的文件的信息,如文件指针、权限等。
8. 资源分配信息:记录了进程所占用的系统资源,如打开的文件数量、使用的设备等。
PCB 的作用包括:1. 进程管理:PCB 存储了操作系统管理进程所需的所有信息。
2. 上下文切换:当操作系统需要切换进程的执行时,可以通过保存当前进程的 PCB 以及恢复下一个进程的 PCB 来实现切换。
3. 进程调度:PCB 中的进程优先级可以用于调度算法的决策,以确定下一个需要执行的进程。
4. 进程同步与通信:PCB 中的状态信息可以用于进程间的同步与通信,如等待、唤醒等操作。
总的来说,PCB 是操作系统中对进程进行管理和控制的重要数据结构,存储了进程的各种信息,通过它可以对进程进行调度、同步和通信等操作。
操作系统实验一模拟进程状态转换

操作系统实验一模拟进程状态转换四、运行结果:图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
进程操作的实验报告

一、实验目的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. 进程创建与销毁:通过创建和销毁进程,验证了进程结构体的正确性。
操作系统实验——动态优先级进程调度实验报告

1.实验名称:动态优先权调度过程中就绪队列的模拟2.实验要求:采用动态优先权的进程调度算法,用C语言编程模拟调度过程中每个时间片内的就绪队列。
3.实验内容:(1)每个进程控制块PCB用结构描述,包括以下字段:*进程标识符id*进程优先数priority,并规定优先数越大的进程,其优先权越高。
*进程已占用的CPU时间cputime*进程还需占用的CPU时间alltime,当进程运行完毕时,aiitime变为0*进程的阻塞时间startblock,当进程再运行startblock个时间片后,进程将进入阻塞状态*进程被阻塞的时间blocktime,已阻塞的进程再等待blocktime个时间片后,将转换成就绪状态*进程状态state*队列指针next,将PCB排成队列。
2)调度前,系统中有五个进程,它们的初始状态如下:3)进程在就绪队列呆一个时间片,优先数增加1。
4)进程每运行一个时间片,优先数减3。
5)按下面格式显示每个时间片内就绪队列的情况:READY_QUEUE:->id1->id24.任务分析进程控制块用结构体来表示,包含它的各项属性。
建立两个队列:一个就绪队列,一个阻塞队列。
创建一个进程控制块表示当前正在运行的进程。
程序开始运行时,所有进程都在就绪队列中。
当startblock减少到0时,进程进入阻塞队列。
在阻塞队列中的进程,当blocktime减少到0时,转入就绪队列。
在就绪队列中的进程,如果优先级比当前正在执行的进程高,就可以取代当前进程获取时间片。
当前进程如果运行完毕,就绪队列中优先级最高的进程就可以成为新当前进程。
5.程序流程图#include〈iostream〉#include〈string〉usingnamespace std;#define LEN5typedefenum STATE{READYBLOCKEND}STATE;//定义进程控制块typedefstruct PCB{int id;int priority;int cputime;int alltime;int startblock;int blocktime;STATE state;}PCB;//定义队列typedefstruct queue{int si ze;PCB*data[LEN];}Queue;PCB ps[LEN];PCB*cp; //进程最大数量//进程状态//就绪//阻塞//完成//进程标识符//进程优先级//已占用的CPU时间//还需占用的CPu时间//阻塞时间//被阻塞时间//进程状态//队列中进程的数量//进程的指针//进程数组//当前正在运行的进程6.程序清单Queue rQueue,bQueue;//就绪队列和阻塞队列//就绪队列按优先级降序排序(使用了冒泡排序法)void rQueueSort(){ PCB*temp;for(int i=0;i<rQueue.size-1;i++){for(int j=0;j<rQueue.size-1-i;j++){if(rQueue.data[j]-〉priority<rQueue.data[j+1]-〉priority){temp=rQueue.data[j];rQueue.data[j]=rQueue.data[j+1];}}rQueue.dataj+1]=temp;}}//初始化void init(){//给进程赋值for(int i=0;i<LEN;i++){ps[i].id=i;ps[i].state=READY;ps[i].cputime=0;ps[i].alltime=3;ps[i].blocktime=0;ps[i].startblock=T;}ps[0].priority=9;ps[1].priority=38;ps[2].priority=30;ps[3].priority=29;ps[4].priority=0;ps[2].alltime=6;ps[4].alltime=4;ps[0].startblock=2;ps[0].blocktime=3;cp=NULL;//当前进程赋空bQueue.size=0;//阻塞队列没有进程for(int i=0;i<LEN;i++){bQueue.data[i]=NULL;rQueue.data[i]=&ps[i];}rQueue.size=5;//所有进程全部进入就绪队列rQueueSort();//对就绪队列排序}//打印void print(){cout〈〈"\nRUNNINGPROG:";if(cp!=NULL){cout〈〈cp->id;}cout<<"\nREADY_QUEUE:";for(int i=0;i<rQueue.size;i++){cout〈〈"-〉"〈〈rQueue.data[i]-〉id; }cout<<"\nBLOCK_QUEUE:";for(int i=0;i<bQueue.size;i++){cout〈〈"-〉"〈〈bQueue.data[i]-〉id; }cout〈〈"\n"<<endl;cout<<"ID\t\t";for(int i=0;i<LEN;i++){cout〈〈ps[i].id<<"\t";}cout<<"\nPRI0RITY\t";for(int i=0;i<LEN;i++){cout〈〈ps[i].priority〈〈"\t";}cout<<"\nCPUTIME\t\t";for(int i=0;i<LEN;i++){cout〈〈ps[i].cputime〈〈"\t";}cout<<"\nALLTIME\t\t";for(int i=0;i<LEN;i++){cout〈〈ps[i].alltime〈〈"\t";}cout<<"\nSTARTBLOCK\t";for(int i=0;i<LEN;i++){cout〈〈ps[i].startblock<<"\t";}cout<<"\nBLOCKTIME\t";for(int i=0;i<LEN;i++){cout〈〈ps[i].blocktime<<"\t";}cout<<"\nSTATE\t\t";for(int i=0;i<LEN;i++){if(ps[i].state==READY){cout<<"READY"<<"\t";}elseif(ps[i].state==BLOCK){cout<<"BLOCK"<<"\t";}elseif(ps[i].state==END){cout〈〈"END"<<"\t";}}cout〈〈endl;}//出队,返回进程指针PCB*pop(Queue*q){PCB*temp;if(q-〉size>0){temp=q-〉data[0];//取出队首进程for(int i=0;i<q-〉size-1;i++){q-〉data[i]=q-〉data[i+1];//其他进程依次向前移动}q->size__;return temp;//返回队首进程}return NULL;}//入队void push(Queue*q,PCB*p){if(q_>size<LEN){q_>data[q_〉size]=p;//将入队的进程放在队尾q_>size++;}return;}//运行进程void run(){if(rQueue.size〉0||bQueue.size〉0){if(cp==NULL){//程序一开始运行时,从就绪队列取出首进程cp=pop(&rQueue);}//当前进程没有结束,但优先级比就绪队列首进程低if(cp_〉alltime〉0&&cp_>priority<rQueue.data[0]_〉priority){}push(&r Queue,c//改变进程状态//从就绪队列取出新的当前进程//修改当前进程的状态 //将当前进程加入阻塞队列 //从就绪队列取出新的当前进程{//当前进程的startblock 为正数时//运行一次减一个时间片//减到0时,修改进程状态//每运行一个时间片//就绪队列中的进程优先级+1//每运行一个时间片//阻塞队列中的进程blocktime-1//将当前进程放入就绪队列 //就绪队列队首进程成为当前进程if (cp-〉alltime==0){cp->state =END ;cp=pop(&rQueue); }//如果当前进程运行结束//startblock 为0,标志着当前进程要进入阻塞状态if (cp —>startblock==0&&cp —>blocktime>0){cp —>state=BLOCK ; push(&bQueue,cp); cp=pop(&rQueue); }elseif (cp —>startblock>0)cp —>st artblock 一; }cp —>alltime ——;if (cp —>alltime==0){cp —>state=END ;for (int i=0;i<rQueue.size;i++){rQueue.data[i]-〉priority++; }for (int i=0;i<bQueue.size;i++){if (bQueue.data[i]-〉blocktime>0){bQueue.data[i]-〉blocktime--; }//当阻塞队列队首进程blocktime 为0时if (bQueue.size 〉0&&bQueue.data[0]-〉blocktime==0){bQueue.data[0]-〉state=READY ;//修改进程状态push(&rQueue,pop(&bQueue));//将阻塞队列首进程取出,放入就绪队列cp —〉priority-=3;//修改当前进程的优先级cp —>cputime++; //当前进程占用CPU 时间片+1 if (cp —>alltime>0){//当前进程还需运行的时间片-1}//每运行一个时间片,就绪队列排一次序rQueueSort();} }//主函数int main(){init();//初始化 print();//打印进程信息 while (1){_sleep(1000);if (rQueue.size==0&&bQueue.size==0){//当两个队列都为空时,结束程序cp-〉state=END ;break ; }run();//运行进程 print();//打印进程信息 }return 0; }7.实验过程记录m 匚:\WINDQWS\system32\cmd.exe程序开始执行,当前进程是优先级最高的1号进程,1号进程的优先级减3、cputime++、执行几次之后,1号进程执行完毕而且优先级也不是最高的了,所以优先级为33的2号进程成为当前进程,开始执行。
PCB[进程控制块作用]
![PCB[进程控制块作用]](https://img.taocdn.com/s3/m/24408a9ca0116c175f0e48ae.png)
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系统中,进程是由进程控制块,进程执行的程序,进程执行时所用数据,进程运行使用的工作区组成。
其中进程控制块是最重要的一部分。
进程控制块是用来描述进程的当前状态,本身特性的数据结构,是进程中组成的最关键部分,其中含有描述进程信息和控制信息,是进程的集中特性反映,是操作系统对进程具体进行识别和控制的依据。
操作系统进程管理实验报告

操作系统进程管理实验报告一、引言在现代计算机科学中,操作系统的进程管理是确保系统高效运行的关键环节。
本实验旨在通过观察和分析操作系统的进程管理行为,深入理解进程的创建、运行和终止过程,以及操作系统如何对进程进行调度和资源分配。
二、实验目标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资源给各个进程。
操作系统作业《模拟进程转换》

实验一进程状态模拟进程状态转换及其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);//重载<<
操作系统进程控制实验报告

操作系统进程控制实验报告一、实验目的本次实验的主要目的是深入理解操作系统中进程控制的概念和机制,通过实际操作和观察,掌握进程的创建、终止、阻塞和唤醒等基本操作,以及进程间的通信和同步方法。
二、实验环境本次实验在装有 Windows 10 操作系统的计算机上进行,使用 C 语言作为编程语言,编译环境为 Visual Studio 2019。
三、实验原理1、进程的概念进程是操作系统中进行资源分配和调度的基本单位,它由程序、数据和进程控制块(PCB)组成。
2、进程的状态进程通常具有就绪、运行和阻塞三种基本状态。
就绪状态表示进程已经准备好执行,只等待被调度;运行状态表示进程正在CPU 上执行;阻塞状态表示进程由于等待某个事件而暂停执行。
3、进程控制进程控制通过操作系统提供的系统调用实现,包括创建进程(CreateProcess)、终止进程(TerminateProcess)、阻塞进程(WaitForSingleObject)和唤醒进程(SetEvent)等。
4、进程间通信进程间通信的方式有多种,如共享内存、消息队列、管道等。
在本次实验中,我们主要使用信号量来实现进程间的同步。
四、实验内容及步骤1、创建进程使用 CreateProcess 函数创建一个子进程,子进程执行一个简单的计算任务,计算 1 到 100 的和,并将结果输出到控制台。
```cinclude <windowsh>include <stdioh>DWORD WINAPI ChildProcess(LPVOID lpParam){int sum = 0;for (int i = 1; i <= 100; i++){sum += i;}printf("Child Process: The sum from 1 to 100 is %d\n", sum);return 0;}int main(){STARTUPINFO si;PROCESS_INFORMATION pi;ZeroMemory(&si, sizeof(si));sicb = sizeof(si);ZeroMemory(&pi, sizeof(pi));if (!CreateProcess(NULL, "ChildProcess", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)){printf("CreateProcess failed (%d)\n", GetLastError());return 1;}WaitForSingleObject(pihProcess, INFINITE);CloseHandle(pihProcess);CloseHandle(pihThread);return 0;}```2、终止进程在父进程中使用 TerminateProcess 函数强制终止子进程,并观察终止后的效果。
操作系统实验 进程状态转换及其PCB的变化

操作系统实验---进程状态转换及其PCB的变化1. 目的:自行编制模拟程序,通过形象化的状态显示,使学生理解进程的概念、进程之间的状态转换及其所带来的PCB内容、组织的变化,理解进程与其PCB间的一一对应关系。
2. 内容及要求:1)设计并实现一个模拟进程状态转换及其相应PCB内容、组织结构变化的程序。
2)独立编写、调试程序。
进程的数目、进程的状态模型(三状态、五状态、七状态或其它)以及PCB的组织形式可自行选择。
3)合理设计与进程PCB相对应的数据结构。
PCB的内容要涵盖进程的基本信息、控制信息、资源需求及现场信息。
4)设计出可视性较好的界面,应能反映出进程状态的变化引起的对应PCB内容、组织结构的变化。
5)代码书写要规范,要适当地加入注释。
6)鼓励在实验中加入新的观点或想法,并加以实现。
7)认真进行预习,完成预习报告。
8)实验完成后,要认真总结,完成实验报告。
3. 程序流程图4.代码部分(1)数据结构部分进程结构体struct PCB{char P_name[10];int P_id;int P_state;int needtime;int lefttime;int P_level;};进程结构体有:进程号,进程状态,进程剩下的时间,进程需要的时间,进程的优先级队列结构体struct Queue{PCB qNode[5];int queueLength;};定义的队列最多有5个进程。
(2)程序解释这里做的是对操作系统课程里面将的“3 状态”的模型的模拟,给它提供的初始状态是有5个进程,而进程所需要的时间和进程的状态都是随机产生的,并把就绪队列里面的进程按照进程的优先级(P_level)进行排序,设置初始状态时没有在运行的程序。
(3)程序的代码//#include <stdafx.h>#include <stdio.h>#include <stdlib.h>#include <time.h>struct PCB{char P_name[10];int P_id;int P_state;int needtime;int leavetime;int P_level;};struct Queue{PCB qNode[5];int queueLength;};int insertQueue(Queue *q,PCB *p){int i=0;if (q->queueLength==0){q->qNode[i]=*p;q->queueLength++;return 1;}else{while(p->P_level<=q->qNode[i].P_level){i++;}for (int j=q->queueLength;j>=i;j--){q->qNode[j]=q->qNode[j-1];}q->qNode[i]=*p;q->queueLength=q->queueLength+1;return 1;}}void setQueue(PCB pcb[5],Queue *ready,Queue *blocked,Queue *finish) {ready->queueLength=0;blocked->queueLength=0;finish->queueLength=0;for (int i=0;i<5;i++){if (pcb[i].P_state==0){insertQueue(ready,&pcb[i]);}else{blocked->qNode[blocked->queueLength]=pcb[i];blocked->queueLength++;}}}void show(Queue ready,Queue blocked,Queue fininsh,PCB run){printf("\n完成队列\n");printf("进程名------优先级------所需时间--------剩余时间\n");for (int i=0;i<fininsh.queueLength;i++){printf("%s%d %d %d%d\n",fininsh.qNode[i].P_name,fininsh.qNode[i].P_id,fininsh.qNode[i].P_level,fininsh.qNod e[i].needtime,fininsh.qNode[i].leavetime);}printf("\n");if (run.needtime!=0){printf("当前正在运行的进程:\n");printf("进程名----------优先级------所需时间--------剩余时间\n");printf("%s%d %d %d%d\n",run.P_name,run.P_id,run.P_level,run.needtime,run.leavetime);}printf("\n");printf("就绪队列\n");printf("进程名----------优先级------所需时间--------剩余时间\n");for ( i=0;i<ready.queueLength;i++){printf("%s%d %d %d%d\n",ready.qNode[i].P_name,ready.qNode[i].P_id,ready.qNode[i].P_level,ready.qNode[i].n eedtime,ready.qNode[i].leavetime);}printf("\n");printf("阻塞队列\n");printf("进程名----------优先级------所需时间--------剩余时间\n");for (i=0;i<blocked.queueLength;i++){printf("%s%d %d %d%d\n",blocked.qNode[i].P_name,blocked.qNode[i].P_id,blocked.qNode[i].P_level,blocked.q Node[i].needtime,blocked.qNode[i].leavetime);}}void P_levelRun(Queue ready,Queue blocked,Queue finish,PCB run){int i_blocked=0;int i_finish=0;while(finish.queueLength!=5){printf("*******************************************************************\n ");int i_ready=0;if (run.needtime!=0){run.leavetime--;if (run.needtime!=0&&run.leavetime==0){finish.qNode[i_finish]=run;finish.queueLength++;i_finish++;run.needtime=0;if (ready.queueLength!=0){run=ready.qNode[i_ready];for (;i_ready<ready.queueLength;i_ready++){ready.qNode[i_ready]=ready.qNode[i_ready+1];}ready.queueLength=ready.queueLength-1;}}else{int temp=run.P_id;if (run.P_level<=ready.qNode[0].P_level){insertQueue(&ready,&run);run.needtime=0;printf("时间片用尽,%s%d进入就绪队列,优先级更高的%s%d开始运行!\n",run.P_name,run.P_id,ready.qNode[0].P_name,ready.qNode[0].P_id);}else{printf("时间片用尽,但是没有更高优先级的进程,%s%d继续运行……\n",run.P_name,run.P_id);}}}else if (run.needtime==0){if (ready.queueLength!=0){run=ready.qNode[i_ready];for (;i_ready<ready.queueLength;i_ready++){ready.qNode[i_ready]=ready.qNode[i_ready+1];}ready.queueLength=ready.queueLength-1;}}if (blocked.queueLength!=0){srand((int) time(0));int temp=rand()%2;if (temp==1){printf("\n%s%d所需资源产生,进程从阻塞队列转到就绪队列……\n",&blocked.qNode[i_blocked].P_name,blocked.qNode[i_blocked].P_id);insertQueue(&ready,&blocked.qNode[i_blocked]);blocked.queueLength=blocked.queueLength-1;if (blocked.queueLength!=0){for (int i=0;i<blocked.queueLength+1;i++){blocked.qNode[i]=blocked.qNode[i+1];}}}else if(temp==0){printf("\n%s%d所需资源没有产生,等待。
操作系统实验进程状态转换及其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变化的影响。
实验结果分析
操作系统进程调度实验报告

操作系统进程调度实验报告一.实验目的用高级语言编写和调试一个进程调度程序~以加深对进程的概念及进程调度算法的解(进程调度时进程管理的主要内容之一~通过设计~编制~调试一个简单的进程调度模拟系统~对进程调度~进程运行状态变换加深理解和掌握。
模拟计算机操作系统的进程调度,建立进程控制块PCB,要包含有关进程的描述信息,控制信息以及资源信息.模拟系统根据PCB感知进程的存在和通过PCB中所包含的各项变量的变化,掌握进程所处的状态以达到控制进程活动的目的.要实现进程的状态及其转换,进程的创建与撤消,进程的阻塞与唤醒.用P,V原语操作实现进程互斥.二.实验要求建立进程控制块PCB,用PCB实现进程在运行过程中的一切状态,未创建、就绪、运行、等待、退出.以完成资源的共享,实现进程的同步与互斥.程序要求用p,v操作实现进程互斥. 三.实验平台Windows XP 下的Microsoft vitual c++平台四.所用语言Microsoft Visual C++语言五.机器要求Microsoft Windows XP Professional版本 2002Service Pack256MB内存SVGA(800×600分辨率~256色或更高级的显示卡鼠标或其他相容设备六.系统分析设计建立四个进程,模拟模拟批处理多道操作系统的进程调度,进程调度算法,采用最高优先数优先的调度算法.每个进程有一个进程控制块, PCB,表示。
进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。
进程的优先数及需要的运行时间可以事先人为地指定,也可以由随机数产生,。
进程的到达时间为进程输入的时间。
进程的运行时间以时间片为单位进行计算。
每个进程的状态可以是就绪 W,Wait,、运行R,Run,、或完成F,Finish,三种状态之一。
就绪进程获得 CPU后都只能运行一个时间片。
用已占用CPU时间加1来表示。
实验2进程状态转换及其PCB的变化

进程创建状态: PCB中记录进程 标识、父进程标 识等基本信息。
进程执行状态: PCB中增加记录 进程执行的CPU 寄存器信息,如 程序计数器、堆 栈指针等。
进程阻塞状态: PCB中记录进程 等待的资源或事 件,以及等待时 间和原因。
进程唤醒状态: PCB中更新进程 等待资源或事件 的状态,并重新 计算进程优先级。
就绪状态中,进程等待 CPU调度,一旦获得 CPU时间片,进程会从 就绪状态变为执行状态 。
进程因等待某个条件成立而无法继续执行 进程被阻塞,等待某个事件发生 进程被唤醒,条件成立,从阻塞状态转换到就绪状态 进程重新进入就绪队列,等待CPU调度执行
进程正常结束 进程异常结束 系统调用终止进程 父进程请求终止子进程
PART FIVE
准备实验器材和材料 按照实验指导书搭建实验电路 连接电源,启动实验设备
观察并记录实验现象和数据 分析实验结果,得出结论 清理实验现场,归还实验器材
准备实验器材和材料
按照实验指导书搭建实验 电路
连接电源,启动实验设备
观察并记录实验数据和现 象
分析实验结果,得出结论
清理实验现场,确保安全
实验结论:根据实验结果,得出实验结论,并指出实验的局限性和改进方向。
图表展示:利用图表展示实验结果,使数据更加直观易懂。
实验结果分析:对实验结果进行详细分析,包括数据对比、图表展示等 实验结论:根据实验结果得出结论,总结实验的成功与不足 实验收获:从实验中获得了哪些知识、技能和经验,如何应用到实际工作中 未来展望:对实验的未来发展进行展望,提出改进和优化的建议
XX,a click to unlimited possibilities
汇报人:XX
CONTENTS
进程与PCB

进程与PCB1、关于进程的执⾏顺序有向⽆循环图(DAG)进程执⾏的特点(1) 顺序性处理机的操作严格按程序规定顺序执⾏(2) 封闭性程序⼀旦开始执⾏,其计算结果不受外界因素影响。
(3) 可再现性程序执⾏只要初始条件⼀样,不论如何停顿,重复执⾏多少次结果都⼀样。
多个程序如果⽆序并发,得到的只能是混乱的执⾏结果,多道程序运⾏,⾛⾛停停的可能顺序有很多种,符合前趋图的关系才是合理并发。
没有任何⼲预下,会出现结果不可再现的并发,即错误的并发。
并发时的特征1、间断性(运⾏表现)相互制约导致并发程序具有“执⾏——暂停——执⾏”这种间断性的活动规律。
2、失去封闭性共享资源,资源状态由多道程序改变,程序运⾏失去封闭性。
即程序运⾏受其他程序的影响。
3、结果不可再现性结果不确定,程序执⾏将没有任何意义。
程序:程序段+数据段进程实体:程序段+数据段+PCB 并发时⽤于程序控制和资源管理的各种信息。
2、进程进程就是⽤于描述、控制程序在内存中并发运⾏的东东。
进程是进程实体的运⾏过程,是系统进⾏资源分配和调度的⼀个独⽴单位。
结构性特征,进程的根本——PCB动态性进程实质上是进程实体的⼀次有⽣命期的执⾏过程。
程序只是静态的⼀组有序指令。
进程最基本特征并发性多个进程实体同存于内存中,在⼀段时间内同时运⾏。
有PCB的程序才能并发。
独⽴性异步性进程的基本状态(1)就绪状态(Ready)(2)运⾏状态(Running)(3)阻塞状态(Blocked)3、PCB系统运⾏中有若⼲个程序的PCB,它们常驻内存的PCB区。
采⽤的数据结构:PCB结构体,PCB链表或队列链接⽅式同⼀状态的PCB,依靠链接指针链接成队列。
就绪队列;若⼲个阻塞队列;空⽩队列(PCB区的空PCB块)索引⽅式同状态的PCB同样集中记录,但以索引表的⽅式记录PCB的地址。
⽤专门的单元记录各索引表的⾸地址。
链接⽅式索引⽅式。
进程切换实验报告

一、实验目的通过本次实验,了解进程切换的基本概念和过程,掌握进程切换的触发条件、切换过程以及切换开销,加深对进程调度和管理的理解。
二、实验环境操作系统: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)。
}
}
void setQueue(PCB pcb[5],Queue *ready,Queue *blocked,Queue *finish)
{
ready->queueLength=0;
blocked->queueLength=0;
finish->queueLength=0;
for (int i=0;i<5;i++)
5)代码书写要规范,要适当地加入注释。
6)鼓励在实验中加入新的观点或想法,并加以实现。
7)认真进行预习,完成预习报告。
8)实验完成后,要认真总结,完成实验报告。
3. 程序流程图
4.代码部分
(1) 数据结构部分
进程结构体
struct PCB
{
char P_name[10];
int P_id;
int P_state;
{
if (pcb[i].P_state==0)
{
insertQueue(ready,&pcb[i]);
}
else
{
blocked->qNode[blocked->queueLength]=pcb[i];
blocked->queueLength++;
}
}
}
void show(Queue ready,Queue blocked,Queue fininsh,PCB run)
}
printf("\n");
if (run.needtime!=0)
{
printf("当前正在运行的进程:\n");
printf("进程名----------优先级------所需时间--------剩余时间\n");
printf("%s%d%d%d%d\n",run.P_name,run.P_id,run.P_level,run.needtime,run.leavetime);
}
}
else
{
int temp=run.P_id;
if (run.P_level<=ready.qNode[0].P_level)
{
insertQueue(&ready,&run);
run.needtime=0;
printf("时间片用尽,%s%d进入就绪队列,优先级更高的%s%d开始运行!\n",run.P_name,run.P_id,ready.qNode[0].P_name,ready.qNode[0].P_id);
blocked.queueLength=blocked.queueLength-1;
if (blocked.queueLength!=0)
{
for (int i=0;i<blocked.queueLength+1;i++)
{
blocked.qNode[i]=blocked.qNode[i+1];
}
}
int P_level;
};
struct Queue
{
PCB qNode[5];
int queueLength;
};
int insertQueue(Queue *q,PCB *p)
{
int i=0;
if (q->queueLength==0)
{
q->qNode[i]=*p;
q->queueLength++;
(3)程序的代码
//#include <stdafx.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct PCB
{
char P_name[10];
int P_id;
int P_state;
int needtime;
int leavetime;
return 1;
}
else
{
while(p->P_level<=q->qNode[i].P_level)
{
i++;
}
for (int j=q->queueLength;j>=i;j--)
{
q->qNode[j]=q->qNode[j-1];
}
q->qNode[i]=*p;
q->queueLength=q->queueLength+1;
pcb[i].P_id=i;
pcb[i].P_state=rand()%2;
pcb[i].P_level=rand()%10+1;
pcb[i].needtime=rand()%2+1;
pcb[i].leavetime=pcb[i].needtime;
}
setQueue(pcb,&ready,&blocked,&finish);
}
else if(temp==0)
{
printf("\n%s%d所需资源没有产生,等待。。\n",&blocked.qNode[i_blocked].P_name,blocked.qNode[i_blocked].P_id);
}
}
show(ready,blocked,finish,run);
}
}
void main()
}
printf("\n");
printf("阻塞队列\n");
printf("进程名----------优先级------所需时间--------剩余时间\n");
for (i=0;i<blocked.queueLength;i++)
{
printf("%s%d%d%d%d\n",blocked.qNode[i].P_name,blocked.qNode[i].P_id,blocked.qNode[i].P_level,blocked.qNode[i].needtime,blocked.qNode[i].leavetime);
{
ready.qNode[i_ready]=ready.qNode[i_ready+1];
}
ready.queueLength=ready.queueLength-1;
}
}
if (blocked.queueLength!=0)
{
srand((int) time(0));
int temp=rand()%2;
{
pcb[i].P_name[0]='P';
pcb[i].P_name[1]='r';
pcb[i].P_name[2]='o';
pcb[i].P_name[3]='c';
pcb[i].P_name[4]='e';
pcb[i].P_name[5]='s';
pcb[i].P_name[6]='s';
pcb[i].P_name[7]='\0';
{
Queue ready,blocked,finish;
PCB pcb[5];
PCB run;
run.needtime=0;
printf("设置了5个进程!\n[说明:进程的状态,所需时间和优先级等是随机产生的。]\n\n\n");
srand((int) time(0));
for (int i=0;i<5;i++)
}
}
void P_levelRun(Queue ready,Queue blocked,Queue finish,PCB run)
{
int i_blocked=0;
int i_finish=0;
while(finish.queueLength!=5)
{
printf("********************************************\n");
printf("各队列的初始信息如下:\n\n");
show(ready,blocked,finish,run);
P_levelRun(ready,blocked,finish,run);
printf("\n5个进程都运行完,停止。\n");
}
(4)截图部分:
{
printf("\n完成队列\n");
printf("进程名------优先级------所需时间--------剩余时间\n");
for (int i=0;i<fininsh.queueLength;i++)
{
printf("%s%d%d%d%d\n",fininsh.qNode[i].P_name,fininsh.qNode[i].P_id,fininsh.qNode[i].P_level,fininsh.qNode[i].needtime,fininsh.qNode[i].leavetime);
int needtime;
intlefttime;
int P_level;
};
进程结构体有:进程号,进程状态,进程剩下的时间,进程需要的时间,进程的优先级