linux内核调度 - 图文(2)

2019-04-23 20:18

对于内核中需要延迟执行的多数任务都可以利用tasklet来完成,由于同类tasklet本身已经进行了同步保护,所以使用tasklet相比软中断要简单的多,而且效率也不错。 bottom half

BH时最早得内核延迟方法,它原始、简单容易控制,因为所有的BH处理程序都被严格地顺序执行——不允许任何两个BH处理程序同时并发执行,即使它们的类型不同也不可以,这样以来BH执行其间减少了许多同步保护。但是BH不得不被淘汰,因为它的“简便”牺牲了多处理器并发处理的高性能,等于一队人过独木桥那样速度受到牵制。 任务队列

任务列队是BH的替代品,来自BH,所以它的属性也和BH相同。它原意在于简化BH的操作接口,但它的随意性(数量随意、执行时机随意)却给系统带来了混乱,所以到今天已经被工作队列(在2.6内核中)所取代。

不过在2.4内核中任务队列还是被大量应用,尤其是调度队列、定时器队列和及时队列等三种任务队列(除了这三种系统已接管的特定任务队列外,你自己也可随心所欲的建立自己的任务队列,当然这时你要自己调度它)。调度队列的任务会在每次进程调度时得到处理,它是在进程上下文中处理的;定时器队列会在每次时钟滴答时得到处理;立即队列会在中断返回或调度时获得处理(所以处理最快),他们都是在中断上下问中处理的。

这些任务队列在内核内由一个统一的内核线程调度,该线程名为keventd,进程号是2(2.4.18)。你可用ps命令查看到该进程。 内核线程

内核线程可以理解成在内核中运行的特殊进程,它有自己的“进程上下”(借用调用它的用户进程的上下文),所以同样被进程调度程序调度,也可以睡眠——它和用户进程属性何其相似,不同之处就在于内核线程运行于内核空间,可访问内核数据,运行期间不能抢占。

传统的Unix系统把一些重要的任务委托给周期性执行的进程,这些任务包括刷新磁盘高速缓存,交换出不用的页框,维护网络链接等等。事实上,以严格线性的方式执行这些任务的确效率不高,如果把他们放在后台调度,不管是对它们的函数还是对终端用户进程都能得到较好的响应。因为一些系统进程只运行在内核态,现代操作系统把它们的函数委托给内核线程(Kernel Thread),内核线程不受不必要的用户态上下文的拖累。 内核中的同步

内核只要存在任务交错执行,就必然会存在对共享数据的并发问题,也就必然存在对数据的保护。而内核中任务交错执行原因归根结底还是由于内核任务调度造成的。我们下面归纳一下内核中同步的原因。 同步原因

? 中断——中断几乎可以在任何时刻异步发生,也就可能随时打断当

前正在执行的代码。

? 睡眠及与用户空间的同步——在内核执行的进程可能会睡眠,这就

会唤醒调度程序,从而导致调度一个新的用户进程执行。 ? 对称多处理——两个或多个处理器可以同时执行代码。

? 内核抢占——因为内核具有抢占性,所以内核中的任务可能会被另

一任务抢占(在2.6内核引进的新能力)。

后两种情况大大加深了内核任务并发执行的可能,使得并发随时随刻都有可能发生,而且不可清晰预见,规律难寻。 内核心任务之间的并发关系

上述内核任务很多情况是可以交错执行的——记住,一个下半部实际上可能在任何时候执行,所以很有可能产生竞争(都要访问同一个数据结构时,就产生了竞争)。下面分析这些内核任务之间有那些可能的并发行为。

可以抽象出,程序(用户态和内核态一样)并发执行的总原因无非是正在运行中得程序被其它程序抢占,所以我们必须看看内核任务之间的抢占关系:

? 中断处理程序可以抢占内核中的所有程序(当没有锁保护时),

包括软中断,tasklet,bottom half和系统的调用、内核线程,甚至也包括硬中断处理程序。也就是说中断处理程序可以和这些所有的内核任务并发执行,如果被抢占的程序和中断处理程序都要访问同一个资源,就必然有可能产生竞争。

? 软件中断也可以抢占内核中的所有任务,所以内核代码(比如,

系统调用、内核线程等)中有数据和软中断共享,就有会有竞争——除此外硬件中断处理程序也有可能被软中断打断,条件是硬中断被其它硬中断打断,软中断随即便获得了执行机会,因为软中断是跟在硬中断后执行的。此外要注意的是,软中断即使是同种类型的也可以并发的运行在不同处理器上,所以它们之间共享数据都会产生竞争。(如果在用一个处理器上软中断之间是不能相互抢占的)。

? 同类的tasklet不可能同时运行,所以对于同类tasklet之间是串

行运行的,他们不会产生并发;但两个不同种类的tasklet有可已在不同处理器上并发运行,如果之间有数据共享就会产生竞争(在同一个处理器上运行的tasklet不发生相互抢占的情况)。 ? Bottom half 无论是否是同类的,即使在不同处理器上也都不能

并发执行,它是绝对串行化的,所以它们之间永远不能产生竞争。任务列队属性基本同BH。

? 系统调用和内核线程这种运行在进程上下文中的内核任务可能

和各种内核任务并发,除了上面提到的中断(软,硬)抢占它产生并发外,它是有可能自发性地主动睡眠(比如在一些阻塞性的操作中),放弃处理器,重新调度其它任务,所以系统调用和内核线程除会与软硬中断(半底等)发生竞争,也会与其他(包括自己)系统调用与内核线程发生竞争。我们尤其要注意这种情况。

注意:tasklet和bottom half是建立在软中断之上的,所以它们也都遵从软中断的调度规则——都可以打断进程上下问中的内核代码(系统调用),都可被硬中断打断——这些都可能产生并发。

内核同步措施

为了避免并发,防止竞争。内核提供了一组同步方法来提供对共享数据的保护。 我们的重点不是介绍这些方法的详细用法,而是强调为什么使用这些方法和它们之间的差别。

Linux使用的同步机制可以说从2.0到2.6以来不断发展完善。从最初的原子操作,到后来的信号量,从大内核锁到今天的自旋锁。这些同步机制的发展伴随Linux从单处理器到对称多处理器的过度;伴随着从非抢占内核到抢占内核的过度。锁机制越来越有效,也越来越复杂。

目前来说内核中原子操作多用来做计数使用,其它情况最常用的是两重锁以及它们的变种,一个是自旋锁,另一个是信号量。我们下来就着重介绍一下这两中锁机制。 自旋锁

自旋锁是专为防止多处理器并发而引入的一种锁,它在内核中大量应用于中断处理等部分(对于单处理器来说,防止中断处理中的并发可简单采用关闭中断的方式,不需要自旋锁)。

自旋锁最多只能被一个内核任务持有,如果一个内核任务试图请求一个已被争用(已经被持有)的自旋锁,那么这个任务就会一直进行忙循环——旋转——等待锁重新可用。要是锁未被争用,请求它的内核任务便能立刻得到它并且继续进行。自旋锁可以在任何时刻防止多于一个


linux内核调度 - 图文(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:Unit 2 Space Invaders课文翻译综合教程四

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: