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. COCOS2DX 3.0 优化提升渲染速度 Auto-batching

    COCOS2DX 3.0 优化提升渲染速度 Auto-batching 近期在看COCOS2DX 3.0的Auto-batching合批与Auto Culling动态缩减功能以下就来细致看看吧:整合好 ...

  2. Android Cocos2dx引擎 prv.ccz/plist/so等优化缓存文件,手把手ida教你逆向project反编译apk库等文件

    前段时间在 Android play 上看到一个非常牛逼的 3D 动态天气预报,效果真的非常炫.二话不说动手 dex2jar.bat/apktool 发现这并没 有什么卵用,在核心的地方看见 nati ...

  3. AWR系列之中的一个——AWR简单介绍

    AWR的全称是Automatic Workload Repository(自己主动负载知识库). 它是通过对照两次快照的方式收集到统计信息.来生成txt或者html页面形式的报告. 通常,通过AWR报 ...

  4. android帧动画,移动位置,缩放,改变透明度等动画解说

    1.苦逼的需求又来了,须要实现一些动画效果,第一个想到的是播放gif图片,可是这样会占包的资源,而且清晰度不高,于是想着程序实现,自己用帧动画+缩放+移动+透明度 实现了一些想要的效果,这里跟大家分享 ...

  5. 运行shell命令

    首先将shell命令命名为.sh文件 将上面的代码保存为test.sh.并 cd 到对应文件夹: chmod +x ./test.sh #使脚本具有运行权限 ./test.sh #运行脚本 假设报错/ ...

  6. 0x31 质数

    poj2689 算根号R的质数,然后把L~R区间(这个很小啊)的合数判下 #include<cstdio> #include<iostream> #include<cst ...

  7. JSTL中的常用EL函数(fn:contains(str,subStr))

    转自:https://blog.csdn.net/u012843873/article/details/53289238 ① fn:toLowerCase ④fn:length fn:length函数 ...

  8. 切换JDK版本quick

    最近遇到一个小问题,同时做两个项目,jdk版本一个是5,一个是6,我也去网上找了找方法,但是感觉不是特别好用,最后自己通过一些环境变量设置的技巧和一些批处理命令来使得这件事情只需要双击,输入一个数字回 ...

  9. [实例]ROS使用OpenCV读取图像并发布图像消息在rviz中显示

    思路: (1)使用opencv读取本地图像 (2)调用cv_bridge::CvImage().toImageMsg()将本地图像发送给rviz显示 一.使用opencv读取本地图像并发布图像消息 ( ...

  10. JS判断客户端是否是iOS或者Android或者ipad(二)

    js判断客户端是IPAD和iphone 多了就不说了,直接上代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22     funct ...