Linux系统的中断、系统调用和调度概述(3)

在说进程调度之前,首先整理下进程可能的各种状态。首先我们知道进程的运行状态是分为核心态和用户态。其他的进程状态包括如下

进程未被执行,但出于就绪状态,只要内核调度它,即可执行

进程正在睡眠中并且存在主存中

进程处于就绪状态,但处在二级存储器中

进程在睡眠中,且在二级存储器中

进程执行完核心态的操作,正要返回用户态时,内核做了进程调度,切换了上下文

进程刚被创建

进程调用了exit,处于僵死状态

进程之间的状态转换示意图如下,箭头指明了转换的方向

Linux系统的中断、系统调用和调度概述

进程的各种状态的转换比较复杂,这里主要关注进程的两个运行状态、睡眠以及从就绪到运行的转换

从示意图中可以看出,当发生中断或者系统调用时,进程由用户态转成核心态。但进程在核心态运行时,是不能被抢占的,因此只有当进程由核心态进入睡眠状态时,或者进程处于用户态时,内核才允许做进程调度,切换上下文。而处于就绪状态的进程当被内核调度开始运行的时候,首先是进入核心态的。

那么为什么,进程在核心态运行的时候,不允许做进程调度呢?因为在核心态运行的时候,需要访问一些全局核心数据结构中的信息。如果运行在核心态时的进程调度,那么会改变内核运行时的进程上下文,而这些不同的进程上下文对同一个核心数据可能会有不同的操作要求,这样将有可能会破坏全局核心数据结构中的信息。为了保证内核核心数据的一致性,当进程处于核心态时,是不允许进行上下文切换的。

这就涉及到另一个问题,中断是在任何时刻都能发生的,并且对中断的处理也可能影响内核数据的一致性。那么,但进程在核心态运行时,对于发生中断的情况又如何保证内核数据的一致性呢?解决的方法大致分为两类,一种是简单地在核心态时,禁止所有的中断,但这样会降低对中断的响应速度;另一种方法是设立临界区,找出操作语句中可能会导致内核数据不一致的地方,然后将这部分设为临界区。但CPU执行临界区代码时,把CPU的执行级别提高,这样就可以屏蔽掉很多的中断,从而保证数据的一致性了。一般,为了保证系统的性能,临界区都很小,并且不会经常出现。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/ad0d32c95352c697edbd32473573d092.html