首页HTML开始的地方

线程状态的

两状态

在操作系统中,进程如果先笼统的分类,就是进程在运行或者进程不在运行。这就是操作系统中的两状态模型。

五状态

如果进程不执行的时候,可能还会有不同的状态,比如说我们什么都准备好了,万事俱备,那么只等待CPU的调度就能运行了,或者是在等待IO设备(打印机等)那么这个进程就要等待这个事件完成之后才能继续运行,所以在Not Running中又分为了两种:

就绪态:准备好了,等待运行

阻塞态:因等待某事情发生才能运行,如等待io

在此之后,我们还加了两个状态,创建和终止,这两个就很好理解,一个是进程刚刚被创建的时候,一个是进程结束的时候。

然后我们就得到了一个五状态转换图:

然后我们看一下各种状态之间是怎么转化的

七状态

我们说进程是需要占用内存空间来运行的,我们想象一个极端一点的例子,如果所有的进程现在都在阻塞态都在等待IO,这样的话,我们CPU就在空闲,我们的CPU的利用率就会变低,这不是我们想看到的。

那么我们现在就在想,我们可不可以把这些在等待的程序交换到外存中区,这样我们就可以腾出来一些内存的空间,来运行新的进程。等在外存中的程序等待的事件等待完了,再换回来。

刚刚我们说的把内存中的程序交换到外存去这个过程就叫做挂起。我们可以把阻塞的程序挂起这样可以让CPU去做其他的事情。但是我们需要强调一点,挂起不一定是要从阻塞态转变的,也可能进程刚刚被创建的时候就被直接挂起了,这样也是有可能的。

那我们再继续分析一下,我们的进程被挂起大多数情况是因为在等待某个事件的发生,那么我们也要分开情况取讨论,哪些进程是已经等待完了的,哪些是还在等待的,这样我们就可以分清楚哪些进程是我们现在可以被换进内存中去的,这样我们就又分为了就绪挂起和阻塞挂起。

那我们接下来看一看七状态的转换图:

看一下这七个状态的转换关系:

————————————————

版权声明:本文为CSDN博主「这里是一只小小琪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_41925919/article/details/104717919


线程状态切换图最复杂的

挂起是放到外存,活动是在内存


二、 进程的状态以及状态切换

  进程执行时的间断性决定了进程可能具有多种状态,最基本的三种状态如下

  ① 就绪状态,当进程已分配到除CPU以外的所有必要资源后,只要再获得CPU,就可以立即运行,进程这时的状态称为就绪状态。在一个系统中可能多个进程处于就绪状态,通常将它们排成一个队列,称为就绪队列。

  ② 执行状态,进程已获得CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态,在多处理机系统中,则有多个进程处于执行状态。

  ③ 阻塞状态,处于执行状态的线程由于发生某事件而暂停无法继续执行时,便放弃处理机而处于暂停状态,此时进程的状态称为阻塞状态,或等待状态封锁状态致使进程阻塞的典型事件有:请求I/O,申请缓冲空间等。,处于阻塞状态的进程也会排成一个队列,可能还会根据不同的阻塞原因排成多个队列。

说明:上图表示三种基本状态之间的相互转化。

引起进程阻塞和唤醒的事件:请求系统服务、请求某种操作、新数据尚未到达、无新工作可做。阻塞和唤醒过程如下图所示:

阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。

阻塞的情况分三种:

4.1、等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入”等待池“中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或者notifyAll()方法才能被唤醒。

4.2、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入”锁池“中。

4.3、其他阻塞:运行的线程执行了sleep()或join()方法,或者发出了i/o请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者i/o处理完毕时,线程重新转入就绪状态。

4.4、当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被synchroniza(同步),获取不到锁标记,将会立即进入锁池状态,等待获取锁标记(这时的锁池里也许已经有了其他线程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程获得锁标记后,就转入就绪状态,等待OS分配CPU时间片;

4.5. suspend() 和 resume()方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的resume()被调用,才能使得线程重新进入可执行状态。典型地,suspend()和 resume() 被用在等待另一个线程产生的结果的情形:测试发现结果还没有产生后,让线程阻塞,另一个线程产生了结果后,调用 resume()使其恢复。

4.6、wait()和 notify() 方法:当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的所有资源,与阻塞状态不同),进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒(由于notify()只是唤醒一个线程,但我们由不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,因此在实际使用时,一般都用notifyAll()方法,唤醒有所线程),线程被唤醒后会进入锁池,等待获取锁标记。

————————————————

版权声明:本文为CSDN博主「子木呀」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_41687938/article/details/119375910


  除了上述三种基本状态外,在一些系统中,新增了挂起状态,引入挂起状态的原因如下

挂起状态:在资源不足的情况下,操作系统对在内存中的程序进行合理的安排,其中有的进程被暂时调离出内存,当条件允许的时候,会被操作系统再次调回内存,重新进入等待被执行的状态即就绪态,系统在超过一定的时间没有任何动作。

  ① 终端用户的请求,当终端用户在自己的程序运行期间发现有可疑问题时,希望暂时使自己的程序静止下来,即使正在执行的进程暂停执行;若此时用户进程正处于就绪状态而未执行,则该进程暂不接受调度,以便用户研究其执行情况或对程序进行修改,这种状态就称为挂起状态。

  ② 父进程请求,有时父进程希望挂起自己的某个子进程,以便考查和修改该子进程,或者协调各子进程间的活动。

  ③ 负荷调节的需要,当实时系统中的工作负荷较重,已可能影响到对实时任务的控制时,可由系统把一些不重要的进程挂起,以保证系统能够正常运行。

  ④ 操作系统的需要,操作系统有时希望挂起某些进程,以便检查运行中的资源使用情况或进行记账。


为了进程的管理,还存在着两种常见的状态,即创建状态和终止状态。

  ① 创建状态,创建一个进程一般需要两步。首先,为一个新进程常见PCB,并填写必要的管理信息;其次,把该进程转入就绪状态并插入就绪队列之中。当创建一个新进程时,系统为其分配了PCB,填写了进程标志等信息,但由于该进程所必需的资源或其他信息(如内存)尚未分配等,此时,进程虽拥有了PCB,但是其自身却未进入内存,即创建工作尚未完成,此时进程还不能被调度运行,其所处的状态就是创建状态。

  ② 终止状态,进程的终止也需要两步。首先,等待操作系统进行善后处理,其次,将其PCB清零,并将PCB空间返回给操作系统。进入终止状态的进程以后不能再执行,但是在操作系统中任然保留一个记录,其中保存状态码和一些计时统计数据,供其它进程收集,一旦其它进程完成对终止状态进程的信息提取后,操作系统将删除该进程。


三、进程间的通信

  1. 互斥

  1. 锁变量

  1. 严格轮换法

  1. Peterson算法

  1. 同步

3.信号量

PV操作

管程

4.死锁

posted @   csnotes  阅读(32)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了

这是页脚html

点击右上角即可分享
微信分享提示