1 可运行队列

(基于实时进程调度)

调度程序中最主要的数据结构式运行队列(runqueue)。可运行队列是给定处理器上的可运行进程的链表,每一个处理器一个。

每一个可投入运行的进程都唯一的归属于一个可运行队列。此外,可运行队列中还包括每一个处理器的调度信息。所以,可运行队列也是每一个处理器最重要的数据结构。

为了避免死锁。要锁住多个执行队列的代码必须总是依照相同的顺序获取这些锁:依照可执行队列地址从低向高的顺序。

注:死锁是指两个或两个以上的进程在运行过程中,因为竞争资源或者因为彼此通信而造成的一种堵塞的现象。若无外力作用。它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

runqueue是一个双向循环队列,一旦调度时机触发,内核又一次计算当前队列中全部进程执行权值。并从中挑选出权值最高的进程作为当前进程投入执行。

其弊端:

)调度时机触发,又一次计算runqueue中每一个进程执行权值,复杂度为O(n)。 且调度性能与内核负载相关。

)runqueue同一时候管理着实时进程与非实时进程(普通进程),内核通过进程属性,如实时或非实时、实时进程优先级、用户进程或内核线程相关因素来计算执行权值count,灵活性低,且不便于理解和维护。

2 优先级数组

每一个执行队列都有两个优先级数组,一个活跃的和一个过期的。是prio_array类型的结构体。优先级数组时一种可以提供O(1)级算法发杂度的数据结构。优先级数组使可执行处理器的每一种优先级都包括一个相应的队列,而这些队列包括相应优先级上的可执行进程链表。

每一个优先级数组还包括一个叫做struct list_head的队列,每一个链表与一个给定的优先级相相应。每一个链表都包括该处理器队列上相应优先级的所有可执行进程。

3 又一次计算时间片

在全部的进程的时间片(CPU分配给各个程序的时间)都用完时,都採用一种显式的方法来又一次计算每一个进程的时间片。

新的Linux调度程序降低了对循环的依赖。取而代之的是它为每一个处理器维护两个优先级数组:既有活动数组也有过期数组。活动数组内的可运行队列上的进程都还有时间片剩余;而过期数组内的可运行队列上的进程都耗尽了时间片。

当一个进程的时间片耗尽时。它会被移至过期数组,但在此之前。时间片已经给它又一次计算好了。

4 schedule()

选定下一个进程并切换到它去运行是通过schedule()函数实现的。当内核代码想要休眠时,会直接调用该函数,另外,假设有哪个进程将被抢占。那么该函数也会被唤起运行。schedule()函数独立于每一个处理器运行。

5 计算优先级和时间片

nice值之所以起名为静态优先级,是由于它从一開始由用户指定后。就不能改变。

动态优先级通过一个关于静态优先级和进程交互性的函数关系计算而来。effective_prio()函数能够返回一个进程的动态优先级。

这个函数以nice值为基数,再加上-5到+5之间的进程交互性的奖励或罚分。

通过一些判断来获取准确反映进程究竟是I/O消耗型的还是处理器消耗型的。

最明显的标准莫过于进程休眠的时间长短了。假设一个进程的大部分时间都在休眠,那么它就是I/O消耗型的。假设一个进程运行的时间比休眠的时间长。那它就是处理器消耗型的。

还有一方面。又一次计算时间片相对简单了。它仅仅要以静态优先级为基础就能够了。在一个进程创建的时候,新建的子进程和父进程均分父进程剩余的进程时间片。

这种分配非常公平而且防止用户通过不断创建新进程来不停地获取时间片。task_timeslice()函数为给定任务返回一个新的时间片。时间片的计算仅仅须要把优先级按比例缩放。使其符合时间片的数值范围要求就能够了。

调度程序还提供了第二种机制以支持交互进程:假设一个进程的交互性很强。那么当它时间片用完后,它会被放置到活动数组而不是过期数组中。

6 睡眠和唤醒

休眠(被堵塞)的进程处于一个特殊的不可运行状态。进程把它自己标记成休眠状态。把自己从可运行队列移出,放入等待队列,然后调用schedule()选择和运行一个其它进程。

唤醒的过程刚好相反:进程被设置为可运行状态,然后再从等待队列中移到可运行队列。

休眠有两种相关的进程状态:TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE。休眠通过等待队列进行处理。

等待队列是由等待某些事件发生的进程组成的简单链表。

内核用wake_queue_head_t来代表等待队列。等待队列能够通过DECLARE_WAITQUEUE()静态创建。也能够由init_waitqueue_head()动态创建。唤醒操作通过函数wake_up()进行。它会唤醒指定的等待队列上的全部进程。

关于休眠有一点须要注意。存在虚假的唤醒。

有时候进程唤醒并非由于它所等待的条件达成了,所以才须要用一个循环处理来保证它等待的条件真正达成。

7 负载平衡程序

毫秒调用一次或者在其它情况下每隔200毫秒调用一次。负载平衡程序调用时须要锁住当前处理器的可运行队列而且屏蔽中断,以避免可运行队列被并发地訪问。


【Linux】进程调度概述的更多相关文章

  1. 【原创】(五)Linux进程调度-CFS调度器

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  2. 【原创】(六)Linux进程调度-实时调度器

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  3. linux进程调度之 FIFO 和 RR 调度策略

    转载 http://blog.chinaunix.net/uid-24774106-id-3379478.html    linux进程调度之 FIFO 和 RR 调度策略 2012-10-19 18 ...

  4. Linux进程调度原理

    Linux进程调度原理 Linux进程调度机制 Linux进程调度的目标 1.高效性:高效意味着在相同的时间下要完成更多的任务.调度程序会被频繁的执行,所以调度程序要尽可能的高效: 2.加强交互性能: ...

  5. Linux学习笔记之三————Linux命令概述

    一.引言 很多人可能在电视或电影中看到过类似的场景,黑客面对一个黑色的屏幕,上面飘着密密麻麻的字符,梆梆一顿敲,就完成了窃取资料的任务. Linux 刚出世时没有什么图形界面,所有的操作全靠命令完成, ...

  6. Linux进程调度原理【转】

    转自:http://www.cnblogs.com/zhaoyl/archive/2012/09/04/2671156.html Linux进程调度的目标 1.高效性:高效意味着在相同的时间下要完成更 ...

  7. Linux进程调度与源码分析(二)——进程生命周期与task_struct进程结构体

    1.进程生命周期 Linux操作系统属于多任务操作系统,系统中的每个进程能够分时复用CPU时间片,通过有效的进程调度策略实现多任务并行执行.而进程在被CPU调度运行,等待CPU资源分配以及等待外部事件 ...

  8. Linux进程调度与源码分析(一)——简介

    本系列文章主要是近期针对Linux进程调度源码进行阅读与分析后的经验总结,分析过程中可能结合部分Linux网络编程的相关知识以便于理解,加深对Linux进程调度的理解和知识分享. 本系列文章主要结合L ...

  9. Linux进程调度(3):进程切换分析

     3.调度函数schedule()分析 当kernel/sched.c:sched_tick()执行完,并且时钟中断返回时,就会调用kernel/sched.c:schedule()完成进程切换.我们 ...

  10. 深度讲解Linux内存管理和Linux进程调度-打通任督二脉

    我在多年的工程生涯中发现很多工程师碰到一个共性的问题:Linux工程师很多,甚至有很多有多年工作经验,但是对一些关键概念的理解非常模糊,比如不理解CPU.内存资源等的真正分布,具体的工作机制,这使得他 ...

随机推荐

  1. 单词数 (STL set集合)

    单词数 Problem Description lily的好朋友xiaoou333近期非常空.他想了一件没有什么意义的事情.就是统计一篇文章里不同单词的总数.以下你的任务是帮助xiaoou333解决问 ...

  2. Redis源代码分析(二十二)--- networking网络协议传输

    上次我仅仅分析了Redis网络部分的代码一部分,今天我把networking的代码实现部分也学习了一遍,netWorking的代码很多其它偏重的是Clientclient的操作.里面addReply( ...

  3. 积跬步,聚小流------Bootstrap学习记录(1)

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...

  4. C++ 浅析 STL 中的 list 容器

    list - 擅长插入删除的链表 链表对于数组来说就是相反的存在. 数组本身是没有动态增长能力的(程序中也必须又一次开辟内存来实现), 而链表强悍的就是动态增长和删除的能力. 但对于数组强悍的随机訪问 ...

  5. elcipse 编译cocos2d-x android

    http://blog.csdn.net/eyu8874521/article/details/22605695 最開始学习cocos2dx.大多数人可能是被复杂的环境配置过程搞死的,尤其是和Andr ...

  6. UVA - 11722 Joining with Friend 几何概率

                            Joining with Friend You are going from Dhaka to Chittagong by train and you ...

  7. 利用flashback transaction query新特性进行事务撤销

    具备了flashback version query查询的基础,我们就可以进行基于flashback version query的恢复.这就是flashback transaction query.f ...

  8. Vmware 安装虚拟工具 (二)

    打开虚拟机,以root超级用户登陆,菜单栏选择虚拟机,install安装虚拟机 拷贝虚拟工具到 在根目录下建立文件夹,并将工具拷贝到该文件夹,例如vmtool 打开终端,进入该目录开始安装 如图,进入 ...

  9. Load和CPU利用率是如何算出来的

    相信很多人都对Linux中top命令里“load average”这一栏困惑过,到底什么是Load,Load代表了什么含义,Load高会有什么后果?“%CPU”这一栏为什么会超过100%,它是如何计算 ...

  10. Excel导入到DataTable ,DataTable导入到Excel

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using NPOI.SS. ...