进程的状态与转换、进程控制

1. 进程的状态与转换

1.1 进程的状态1

进程是程序的一次执行。在这个执行的过程中,有时进程正在被CPU处理,有时又需要等待CPU服务,可见,进程的状态是会有各种变化。为了方便对各进程的管理,操作系统需要将进程合理地划分为几种状态。


三种基本运行状态

  • 运行态(Running):占有CPU,并在CPU上运行

注意:单核处理机(CPU)环境下,每一时刻最多只有一个进程处于运行态。(双核环境下可以同时有两个进程处于运行态)

  • 就绪态(Ready):已经具备运行条件,但由于没有空闲CPU,而暂时不能运行

该状态下的进程已经拥有了除处理机(CPU)之外所有需要的资源,一旦获得处理机,即可立即进入运行态开始运行。即:万事俱备,只欠CPU。

  • 阻塞状态(Waiting/Blocked,又称:等待态):因等待某一事件而暂时不能运行

如:等待操作系统分配打印机、等待读磁盘操作的结果。CPU是计算机中最昂贵的部件,为了提高CPU的利用率,需要先将其他进程需要的资源分配到位,才能得到CPU的服务


另外两种状态

  • 创建态()New,又称:新建态:进程正在被创建,操作系统为进程分配资源、初始化PCB

操作系统需要完成创建进程。操作系统为该进程分配所需的内存空间等系统资源,并为其创建、初始化PCB(如:为进程分配PID)

  • 终止态(Terminated,又称:结束态):进程正在从系统中撤销,操作系统会回收进程拥有的资源、撤销PCB

进程运行结束(或者由于bug导致进程无法继续执行下去,比如数组越界错误),需要撤销进程。
操作系统需要完成撤销进程的工作。完成将分配给进程的资源回收,撤销进程PCB等工作

1.2 进程状态间的转换

在这里插入图片描述

  • 就绪态—>运行态:进程被调度,需恢复进程运行环境、修改PCB内容和相应队列。
  • 运行态—>就绪态(进程切换):时间片到,或CPU被其他高优先级的进程抢占,需保存进程运行环境、修改PCB内容和相应队列。
  • 运行态—>阻塞态:等待系统资源分配,或等待某件事发生(主动行为),需保持进程运行环境、修改PCB内容和相应队列。
  • 阻塞态—>就绪态:资源分配到位,等待的事件发生(被动行为),需修改PCB内容和相应队列。如果等到的是资源,则还需为进程分配系统资源。
  • 创建态—>就绪态:系统完成创建进程相关的工作,需修改PCB内容和相应队列。
  • 运行态—>终止态:进程运行结束,或运行过程中遇到不可修复的错误

2. 进程控制

2.1 基本概念

什么是进程控制?
进程控制的主要功能是对系统中所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能。

简化理解:反正进程控制就是实现进程状态转换如何实现进程控制?用“原语”实现

如何实现进程控制?
原语实现进程控制。原语的特点是执行期间不允许中断,只能一气呵成。这种不可被中断的操作即原子操作
原语采用“关中断指令”和“开中断指令”实现
显然,关/开中断指令的权限非常大,必然是只允许在核心态下执行的特权指令

2.2 进程控制的相关原语

学习技巧:进程控制会导致进程状态的转换。无论哪个原语,要做的无非三类事情:

  1. 更新PCB中的信息(如修改进程状态标志、将运行环境保存到PCB、从PCB恢复运行环境)

    a. 所有的进程控制原语一定会修改进程状态标志
    b. 剥夺当前运行进程的CPU使用权必然需要保存其运行环境
    c. 某进程开始运行前必然要恢复其运行环境

  2. 将PCB插入合适的队列
  3. 分配 / 回收资源
  • 进程的创建

    • 创建原语(无—>创建态—>就绪态)
      • 申请空白PCB
      • 为新进程分配所需资源
      • 初始化PCB
      • 将PCB插入就绪队列
    • 引起进程创建的事件
      • 用户登录:分时系统中,用户登录成功,系统会为其建立一个新的进程
      • 作业调度:多道批处理系统中,有新的作业放入内存时,会为其建立一个新的进程
      • 提供服务:用户向操作系统提出某些请求时,会新建一个进程处理该请求
      • 应用请求:由用户进程主动请求创建一个子进程
  • 进程的终止

    • 撤销原语(就绪态 / 阻塞态 / 运行态—>终止态 —>无)
      • 从PCB集合中找到终止进程的PCB
      • 若进程正在运行,立即剥夺CPU,将CPU分配给其他进程
      • 终止其所有子进程
      • 将该进程拥有的所有资源归还给父进程或操作系统
      • 删除PCB
    • 引起进程终止的事件
      • 正常结束
      • 异常结束
      • 外界干预

进程的阻塞和唤醒2

  • 进程的阻塞
    • 阻塞原语(运行态—>阻塞态)
      • 找到要阻塞的进程对应的PCB
      • 保护进程运行现场,将PCB状态信息设置为“阻塞态”,暂时停止进程运行
      • 将PCB插入相应事件的等待序列
    • 引起进程阻塞的事件
      • 需要等待系统分配某种资源
      • 需要等待相互合作的其他进程完成工作
  • 进程的唤醒
    • 唤醒原语(阻塞态—>就绪态)
      • 在事件等待队列中找到PCB
      • 将PCB从等待队列移除,设置进程为就绪态
      • 将PCB插入就绪队列,等待被调度
    • 引起进程唤醒的事件
      • 等待的事件发生:因何事阻塞就应由何事唤醒

  • 进程的切换
    • 切换原语(运行态—>阻塞态/就绪态 就绪态—>运行态)
      • 将运行环境信息存入PCB
      • PCB移入相应队列
      • 选择另外一个进程执行,并更新其PCB
      • 根据PCB恢复新进程所需的运行环境
    • 引起进程切换的事件
      • 当前进程事件片到
      • 有更高优先级的进程到达
      • 当前进程主动阻塞
      • 当前进程终止

  1. 以上笔记均来自王道考研 ↩︎

  2. 阻塞原语唤醒原语必须成对使用 ↩︎

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
流程图,代码,截图三、程序源代码: #include"stdlib.h" #include"stdio.h" #include"string.h" /********** globle structure and viable ******/ struct PCB { int P_Id; //PCB的ID号 char P_Name[10]; //PCB的名称 char P_State[10]; //PCB状态 int P_Runtime; //PCB的所需要的运行时间 int P_Requiry; //PCB所需要的资源要求 struct PCB * next ; //PCB块的下一个指针 } ; struct PCB * Create_state; //创建状态 struct PCB * Run_state; //运行状态 struct PCB * Ready_state; //就绪状态 struct PCB * Block_state; //阻塞状态 struct PCB * Exit_state; //退出状态 int signal4=0; //标示进程4的完成状态 int signal5=0; //标示进程5的完成状态 void InsertQueue(struct PCB **head,struct PCB *node) /* insert node function */ { struct PCB * p,*q; node->next=NULL; if(*head==NULL) //如果队列为空 { *head=node; } Else //队列不空 { p=*head; q=p->next; while(q!=NULL) //找到最后的元素位置 { p=q; q=q->next; } p->next=node; //将节点插入队列 } } void DeleteQueue(struct PCB **head,struct PCB *node) //撤销进程,从队列中删除元素 { struct PCB *p,*q; q=*head; 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 : %d \n",node->P_Id); printf("this process name is : %s \n",node->P_Name); printf("this process state is : on %s \n ",node->P_State); printf("this process Runtime is : %d \n",node->P_Runtime); if(node->P_Requiry) printf("this process resource is ready \n"); else printf("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); } } 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 readyqueue { //从阻塞状态调度到就绪状态函数 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"); InsertQueue(&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]; strcpy(name,"process"); for(i=1;iP_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); //同时调度到阻塞队列 } for(i=3;iP_Id=i; name[7]=i+'0'; name[8]='\0'; strcpy(p->P_Name,name); strcpy(p->P_State,"create"); p->P_Requiry=1; if(i==6) //在这里个进程6所需要的时间片为2 p->P_Runtime=2; else p->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; while(p!=NULL) { sleep(2); //printf("\n\n///////////////////////////////////\n"); printf("\n\nthis process Id is : %d \n",p->P_Id); printf("this process name is : %s \n",p->P_Name); printf("this process state is : on %s \n ",p->P_State); printf("this process Runtime is : %d \n",p->P_Runtime); if(p->P_Requiry) printf("this process resource is ready \n"); else printf("this process resource is not ready ! \n"); p=p->next; } } void Process_Run() //进程运行函数 { struct PCB *p,*q; p=Ready_state; q=p; while(p!=NULL) //就绪队列不空则继续执行 { if(p->P_RuntimeP_State,"running"); Display_Process(p); p->P_Runtime=p->P_Runtime-1; sleep(4); if(p->P_Runtime>0) //没有完成,则进入就绪队列 { 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[]) //主函数 { int i; char c='c'; //界面 printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \n"); printf("...................................Ding Hai bo\n"); printf("......Press 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(); //调用进程运行函数 } 都有
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值