抢占式内核和非抢占式内核,时间片轮转调度中的抢占与非抢占

 操作系统分为抢占式内核(抢占式调度)和非抢占式内核(非抢占式调度),通常RTOS都是抢占式内核

非抢占式内核:

非抢占式内核要求任务(线程)必须做一些具体的事情,放弃对cpu的使用权,将cpu资源给其他任务(线程)使用,来达到多任务并发。

非抢占式内核(非抢占式调度)也称为多任务协作,任务相互协作,共享CPU,异步事件仍然由ISR(中断处理机制)处理。各个进程之间没有优先级关系,每个进程轮转的时间片大小是系统根据他的负载或者其他的一些特性来动态确定的。只有在时间片计数到规定了,让当前进程自动转入休眠,将这个进程放入到就绪队列尾部,并释放CPU控制权。然后系统进行调度,进程就绪队列的下一个进程开始运行它的时间片,按照就绪队列,顺序执行。

非抢占式内核可以理解为非抢占式调度,linux kernel就是非抢占式。

时间片轮转:

时间片轮转是操作系统实现并发的方式,操作系统为每个进程分配一定的时间片(每个进程的时间片大小不同),当前进程时间片用尽,则切换到下一个就绪进程执行。实现时间片轮转的方式就是通过中断。

1.设置定时芯片每隔Nms发出时钟中断

2.时钟中断的执行步骤:

       (1)获取当前任务结构

       (2)将当前任务时间片-1

       (3)判断当前任务时间片是否有剩余

       (4)如果有剩余,那么就返回这个任务继续执行(时间片没有用完,除非中断和异常,不然不会释放CPU控制权,也就是不会进行调度)

       (5)如果没有剩余,那么判断当前任务是内核任务还是用户任务

       (6)如果是内核任务,且不可被抢占,那么直接中断返回到内核任务(假设此处内核任务是不可被抢占的)

       (7)如果是用户任务,则执行任务调度,完成任务切换

时间片轮转是操作系统实现并发的方式,操作系统为每个进程分配一定的时间片,当前进程时间片用尽,则切换到下一个就绪进程执行。实现时间片轮转的方式就是通过中断,将当前执行的进程放到就绪队列,然后使用进程调度函数进行进程切换。

比如当前执行进程时间片是1ms,这时候时钟中断每隔0.1ms就进入中断,判断当前时间片是否执行完毕,如果时间片没有完毕,那么中断会回到系统原来的状态。除非当前进程在中断中判断时间片已经完成,才会进行调度。(这个判断时间片是否完成的中断,可以当他没有发生过)

非抢占式图解:

举个例子:

假设时间片大小为0.1,进程之间不区分优先级。

 进程1的是时间片运行到8.5的时候有第二个进程开始运行了,那么运行状态就装入了进程2,然而进程1的时间片没有用完,所以他们两个交替执行,第三第四个进程也类似。

非抢占式内核的优点:

(1)中断响应快

(2)允许使用不可重入型函数

(3)运行的任务占用CPU,不必担心被别的任务抢占

非抢占式内核的缺点:

(1)任务响应时间慢,高优先级的任务已经进入就绪状态,但是还不能运行

(2)非抢占式内核的任务响应时间不确定,不知道什么时候最高优先级的任务才能拿到CPU的控制权,完全取决上一个进程什么时候释放CPU的控制权。

抢占式内核:

一般的RTOS都是抢占式内核

使用抢占式内核,最高优先级任务的执行是确定性的;你可以确定它何时可以控制 CPU。因此,通过使用抢占式内核可以最大限度地减少任务级响应时间。

每个进程运行时间,时间片到了后,下一个进程必须是所有pending的进程里面最高优先级的进程执行,设计者可以预知系统是怎么运行的。(很多文章中的,进程结束就是你所分配的时间片论转到达限定值了,但并不是进程执行完不跑了)

进程之间是不可以抢占的,如果时间片没有到达时间,那么这个进程是不能被其他进程抢占的,除非遇到中断和异常。抢占的意思是pending的进程里高优先级的会排在前面。而不是进程之间相互抢占。一个进程时间片轮转结束之后,下一个进程是就绪队列中,优先级最高的队列。

每个进程能运行多长时间是由时间片来决定的,另一个进程想运行,必须等到前一个进程时间片结束,抢占就是,当前进程时间片结束了,系统想挑选另外的进程来运行,这个另外的进程必定是所有pending的进程优先级最高的。如果当前执行的进程优先级比较低,那么肯定把CPU的控制权分给优先级较高的进程,那么之前那个优先级较低的进程就会被挂起,由于每次时间片结束,都会挑选优先级较高的进程运行,那么那个优先级最高的进程就会一直获得时间片,也就一直获得cpu控制权了,除非这时候来了个更高优先级的,或者原来的进程进入了阻塞。(非实时系统就没有这种机制)

总而言之,抢占式内核始终执行准备运行的最高优先级任务。中断抢占任务,完成 ISR 后,内核将继续执行准备运行的最高优先级任务(而不是被中断的任务)。任务级别的响应是最佳的和确定性的,当系统响应性很重要时,建议使用抢占式内核。

抢占式图解:

对于时间片轮转调度算法中的抢占式,举个栗子说明:

一开始8.0时刻,只有进程A,这时候进程A获得cpu控制权,进程A每次时间片运行完,都会检查是否pending中有更高优先级,如果没有就会继续运行,进程A一直运行到8.05时刻。

这时候进程B创建,进程B的优先级明显比进程A高,那么进程A时间片运行完,就会运行进程B,此时进程A挂起态。这时候pending中有进程A和进程B两个进程。

进程B每次运行完时间片,都会检查pending中是否有优先级跟高的进程,没有的话,那么自己优先级最高,就先占用时间片,获得CPU控制权。即使到8.08.进程C创建,那么pending中优先级最高的仍然是进程B,所以进程B继续运行。

一直到8.15,进程B运行完毕,此时pending中有进程A和进程C,由于进程A优先级较高,所以先运行进程A。

下面同理。一个进程每次运行时间片结束后,都会检查pending中是否有优先级较高的进程,没有的话,自己继续占用时间片,也就是cpu控制权。

抢占式内核的优点:

(1)最高优先级的任务什么时候可以执行,可以得到CPU的使用权是已知的,使用抢占式内核使任务响应时间得到最优化。

抢占式内核的缺点:

(1)不能直接使用不可重入型函数,调用不可重入函数时,要满足互斥条件。否则调用不可重入型函数的话,低优先级的任务CPU使用权就被高优先级任务剥夺,不可重入型函数的数据有可能被破坏。

重入型函数和不可重入型函数

在实时系统的设计中,经常会出现多个任务调用同一个函数的情况。如果有一个函数不幸被设计成为这样:那么不同任务调用这个函数时可能修改其他任务调用这个函数的数据,比如函数中的变量等。我进程A使用全局变量x,还没有使用完x的结果,就调用了进程B,那么我进程B如果也使用了全局变量x,那么就会导致x最后结果不确定。从而导致不可预料的后果。这样的函数是不安全的函数,也叫不可重入函数

相反,肯定有一个安全的函数,这个安全的函数又叫可重入函数。那么什么是可重入函数呢?所谓可重入是指一个可以被多个任务调用的过程,任务在调用时不必担心数据是否会出错。

(105条消息) 浅谈可重入函数与不可重入函数_lianghe_work的博客-CSDN博客

这也就是为什么,驱动中我们尽量少使用全局变量,因为多个同类设备,可能使用一个驱动,反复调用,如果驱动中使用了全局变量,那么每个设备调用的驱动都能更改这个全局变量,那么最后这个变量的结果就不确定了。

介绍完抢占式内核和非抢占式内核,我们知道操作系统运行时候,分为两种状态,分别是用户态和内核态。

那么这两种状态就引出另外两个知识点,linux用户抢占和linu内核抢占。了解清楚后再分享!

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值