HACK #8 调度策略

本节介绍Linux的调度策略(scheduling policy)。
Linux调度策略的类别大致可以分为TSS(Time Sharing System,分时系统)和实时系统这两种。
一方面,一般的进程是通过分时运行的。也就是说,使用CPU的时间达到分配给进程的时间(时间片)时,就会切换到其他进程。这种分时运行的调度策略称为TSS。
另一方面,在实时制约较严格且要求保证实时的处理中,就需要指定静态的执行优先级,并严格按照执行优先级进行调度。对这种对应答性有要求的进程,可以使用实时调度策略。另外,与TSS调度策略的进程相比,CPU将优先分配给使用实时调度策略的进程。
在Linux中,进程的静态优先级为0~99。TSS调度策略的优先级为0,实时调度策略的优先级可以指定的范围为1~99。
Linux 2.6.23以前一直采用的O(1)调度程序,还会在TSS调度策略中添加动态优先级。长时间持续使用CPU的进程,其调度的动态优先级会渐渐降低。Linux的进程调度程序是按照优先级来分配CPU的,因此长时间占用CPU的进程优先级与其他进程相比就相对较低。与之相对的是,频繁与用户进行交流的shell等对话进程由于CPU使用时间短,其调度的优先级变高,更容易分配到CPU。因此,为等待用户输入而立刻腾出CPU的shell进程的优先级变得比其他进程高,用户的应答性就得到提高。
在Linux 2.6.23导入的CFS(Completely Fair Scheduler)调度程序中,没有之前的O(1)调度程序所进行的经验性优先级变化。CFS通过称为公平的CPU时间分配的结构来运行。
调度策略
RHEL6(Linux 2.6.32)中定义了下列调度策略。

SCHED_OTHER
SCHED_FIFO
SCHED_RR
SCHED_BATCH
SCHED_IDLE

下面将分别对各调度策略进行介绍。

SCHED_OTHER

这是Linux的标准调度策略,也是所谓TSS调度策略。
在RHEL5等Linux 2.6.23之前的内核所使用的以优先级为基础的O(1)调度程序中,还加入了经验性的判断,优先为会话进程赋予执行权。TSS的时间片由优先级决定。
在RHEL6等Linux 2.6.23之后的CFS中,会公平地为所有TSS策略的进程分配CPU时间。其时间片是动态决定的。

SCHED_FIFO

这是实时调度策略,即具有静态优先级的调度策略。Linux内核中能够为实时调度策略的进程指定的优先级为1~99。使用了SCHED_FIFO调度策略的进程,除了等待I/O完成时休眠、自发休眠或优先级更高的实时进程获得优先权以外,不会释放执行权。
使用SCHED_FIFO的实时调度策略时,需要注意的是,它的进程不会自动释放CPU,也就是说执行权不会转移到其他进程。例如,实时调度策略的进程陷入无限循环时,其他所有优先级较低的进程永远不会被赋予执行权,此时系统就会死机。
小贴士:另外,要对进程使用实时调度策略,必须有root权限。

SCHED_RR

这也是实时调度策略。RR是round robin(轮询)的缩写,与SCHED_FIFO不同的是,它具有时间片。时间片使用完时,执行权将转移到其他进程。
在2.6.23以前导入的O(1)调度程序中,时间片是由优先级决定的。
引入CFS时SCHED_RR的调度策略也进行了修改,时间片变为固定值(100毫秒)。

SCHED_BATCH

指定这个调度策略的进程不是会话型,不会根据休眠时间更改优先级。
例如,备份处理等需要进行较大文件或大量文件存取的进程,是通过磁盘I/O来中止的。在TSS调度策略中,因为这个休眠,正在进行备份处理的进程优先级提高,需要应答性的shell等的优先级相对降低。这就会导致系统的应答性降低。
在RHEL5的O(1)调度程序中,使用了这个调度策略的进程被识别为休眠时间为0的CPU bound进程。因此,优先级必然会变成比会话型shell进程低。
对非会话型的进程(即所谓的补丁处理)使用这个调度策略,就可以使会话型进程的优先级保持相对较高,并确保应答性。
在Linux 2.6.23导入的CFS中,对进行补丁处理的进程改变了处理的方法,优先级不会因休眠时间而发生变化。在导入CFS的RHEL6中,SCHED_BATCH和SCHED_OTHER几乎没有区别,因此可以不使用。

SCHED_IDLE

这是由CFS导入的新等级。CPU空闲时,即SCHED_IDLE等级以外处于可执行状态的进程消失时,将被赋予执行权。也就是它将成为优先级最低的进程。
特殊标志:SCHED_RESET_ON_FORK
为了限制实时调度策略的进程运行,而为调度策略添加了标志flag。设置了标志flag的实时调度策略进程,在执行fork()时,新生成的子进程就成为SCHED_OTHER策略的进程。
如下例所示,通过向实时调度策略添加标志flag来设置。

sched_setscheduler(pid, SCHED_FIFO|SCHED_RESET_ON_FORK, &param);

关于调度策略的系统调用
关于调度策略的系统调用如下所示。

sched_setscheduler()

更改调度策略和进程优先级。

sched_getscheduler()

获取当前调度策略与进程优先级。

sched_setparam()

更改调度参数(即进程优先级)。

sched_getparam()

获取当前调度参数。

sched_get_priority_max()
sched_get_priority_min()

获取调度策略的进程的静态优先级范围。

sched_rr_get_interval()

获取当前时间片。
chrt命令
用户使用chrt命令可以很简单地更改调度策略。RHEL5版本的chrt命令中不存在指定SCHED_IDLE的-i选项。
在CentOS5(RHEL5)中chrt的使用方法如下所示。

$ chrt --help
chrt (util-linux 2.13-pre7)
usage: chrt [options] [prio] [pid | cmd [args...]]
manipulate real-time attributes of a process
-b, --batch set policy to SCHED_BATCH
-f, --fifo set policy to SCHED_FF
-p, --pid operate on existing given pid
-m, --max show min and max valid priorities
-o, --other set policy to SCHED_OTHER
-r, --rr set policy to SCHED_RR (default)
-h, --help display this help
-v, --verbose display status information
-V, --version output version information

下面是Fedora 12(RHEL6)中chrt的使用方法。

$ chrt --help

chrt - manipulate real-time attributes of a process.

Set policy:
chrt [options] <policy> <priority> {<pid> | <command> [<arg> ...]} Get policy:
chrt [options] {<pid> | <command> [<arg> ...]} Scheduling policies:
-b | --batch set policy to SCHED_BATCH
-f | --fifo set policy to SCHED_FIFO
-i | --idle set policy to SCHED_IDLE
-o | --other set policy to SCHED_OTHER
-r | --rr set policy to SCHED_RR (default) Options:
-h | --help display this help
-p | --pid operate on existing given pid
-m | --max show min and max valid priorities
-v | --verbose display status information
-V | --version output version information

使用chrt命令,可以更改进程的调度策略和优先级。例如,使用SCHED_IDLE解压缩内核源代码存档时的命令行如下所示。

$ chrt -i o tar jxf linux-2.6.33.tar.bz2

正在运行的进程的调度策略也可以通过指定目的进程的PID来更改。

# chrt -p -r 99 <pid>

另外,使用实时调度策略,必须具有root权限。
小结
本节介绍了可以使用Linux进程调度程序指定的调度策略。可以尝试修改对备份处理和要求实时性的进程的调度策略。
参考文献
CFS
http://www.ibm.com/developerworks/jp/linux/library/l-cfs/?ca=dnj-0208
man sched_setscheduler他
http://www.linux.or.jp/JM/html/LDP_man-pages/man2/sched_setscheduler.2.html
—Hiroshi Shimamoto

精《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #8 调度策略的更多相关文章

  1. 《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #1 如何获取Linux内核

    HACK #1 如何获取Linux内核 本节介绍获取Linux内核源代码的各种方法.“获取内核”这个说法看似简单,其实Linux内核有很多种衍生版本.要找出自己想要的源代码到底是哪一个,必须首先理解各 ...

  2. 《Linux内核精髓:精通Linux内核必会的75个绝技》目录

    1章 内核入门HACK #1 如何获取Linux内核HACK #2 如何编译Linux内核HACK #3 如何编写内核模块HACK #4 如何使用GitHACK #5 使用checkpatch.pl检 ...

  3. 《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #15 ramzswap

    HACK #15 ramzswap 本节介绍将一部分内存作为交换设备使用的ramzswap.ramzswap是将一部分内存空间作为交换设备使用的基于RAM的块设备.对要换出(swapout)的页面进行 ...

  4. 《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #3 如何编写内核模块

    HACK #3 如何编写内核模块 本节将介绍向Linux内核中动态添加功能的结构—内核模块的编写方法.内核模块Linux内核是单内核(monolithic kernel),也就是所有的内核功能都集成在 ...

  5. 精《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #7 Cgroup、Namespace、Linux容器

    HACK #7 Cgroup.Namespace.Linux容器 本节将介绍Cgroup与Namespace以及通过这两个功能实现的容器功能.CgroupCgroup(control group)是将 ...

  6. 精《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #5 使用checkpatch.pl检查补丁的格式

    HACK #5 使用checkpatch.pl检查补丁的格式 本节介绍发布前检查补丁格式的方法.Linux内核是由多个开发者进行开发的.因此,为了保持补丁评估与源代码的可读性,按照统一的规则进行编写是 ...

  7. 精《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #4 如何使用Git

    HACK #4 如何使用Git 本节介绍Git的使用方法.Git是Linux内核等众多OSS(Open Source Software,开源软件)开发中所使用的SCM(Source Code Mana ...

  8. 《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #21FUSE

    HACK #21FUSE 本节将介绍使用用户进程的文件系统框架—FUSE.FUSE概要FUSE(Filesystem in Userspace,用户空间文件系统),是用来生成用户空间的一般进程的框架. ...

  9. 《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #20 使用fio进行I/O的基准测试

    HACK #20 使用fio进行I/O的基准测试 本节介绍使用fio进行模拟各种情况的I/O基准测试的操作方法.I/O的基准测试中有无数需要考虑的因素.是I/O依次访问还是随机访问?是通过read/w ...

随机推荐

  1. Undertow,Tomcat和Jetty服务器配置详解与性能测试

    undertow,jetty和tomcat可以说是javaweb项目当下最火的三款服务器,tomcat是apache下的一款重量级的服务器,不用多说历史悠久,经得起实践的考验.然而:当下微服务兴起,s ...

  2. Linux编写一个C程序HelloWorld

    环境 需要文本编辑器和编译器,文本编辑器用linux(我用的centos7)自带的vi,编译器用gcc(GNU C Compiler/GNU Compiler Collection) 安装gcc,查看 ...

  3. [oracle]创建查看 LOCAL INDEX

    create index IDX_T_GPS_CPH_local on T_GPS (CPH) local; create index IDX_T_GPS_SJ_local on T_GPS (SJ) ...

  4. git源代码管理工具

    git是一款源代码管理工具 是分布式版本管理工具 分布式管理必须先在本地提交然后才能提交到服务器: svn集中式版本管理工具 集中式版本管理工具离开服务器就做不了版本管理: 初始化仓库 1.用git初 ...

  5. HDU 1241 Oil Deposits bfs 难度:0

    http://acm.hdu.edu.cn/showproblem.php?pid=1241 对每个还未访问的点bfs,到达的点都标为一块,最后统计有多少块即可 #include <cstdio ...

  6. -webkit新属性 image-set和srcset

    响应式图片的作用: 为使用不同分辨率的不同浏览器用户提供适合其浏览环境的图片大小的解决方案. 之前的解决方法是使用@media 但是-webkit新提出的image-set和srcset同样可以解决问 ...

  7. [Tomcat无法启动]'Starting Tomcat v8.0 Server at localhost' has encountered a problem.

    运行一个index.jsp,运行提示如下错误:点击服务器 解决办法1: 点击Tomcat服务器,将服务器里的web工程删除掉,再重新运行index.jsp. 解决办法2: 关闭Tomcat,最简单的方 ...

  8. 公式中表达单个双引号【"】和空值【""】的方法及说明

    http://club.excelhome.net/thread-661904-1-1.html 有人问为什么不用三个双引号"""来表示单个双引号["]呢,如果 ...

  9. [QT_FFMPEG]学习问题: 刚开始移植ffmpeg,测试时出现 undefined reference to `avcodec_configuration()'

    使用环境: window: win7 x64 QT: qt5.8.0 MinGW530 移植的教程: 流若浅  Qt ffmpeg环境搭建 : http://www.cnblogs.com/liuru ...

  10. java第十次面试题

    一.给定一个字符串,把字符串内的字母转换成该字母的下一个字母,a换成b,z换成a,Z换成A,如aBf转换成bCg,字符串内的其他字符不改变,给定函数,编写函数. public static void ...