Linux系统是抢占式多任务操作系统,是否要将一个进程立刻投入运行(也就是抢占当前进程),完全由该进程的优先级和是否有时间片来决定。但 CFS调度器:抢占时机取决于新的可执行程序消耗了多少处理器使用比,如果消耗的使用比当前进程小:新程序立刻投入运行,抢占当前进程,否则推迟。

在Linux中,线程是由进程来实现,线程就是轻量级进程,因此线程的调度是按照进程的调度方式来进行调度的,也就是说线程是基本调度单元。

进程提供了两种优先级,一种是普通的进程优先级,第二个是实时优先级。前者适用SCHED_NORMAL(SCHED_OTHER)调度策略,后者可选SCHED_FIFO或SCHED_RR调度策略。任何时候,实时进程的优先级都高于普通进程优先级,实时进程只会被更高级的实时进程抢占,同级实时进程之间是按照FIFO或者RR规则调度。

1. 实时优先级(静态优先级)

实时进程,只有静态优先级,因为内核不会根据休眠等因素对其静态优先级做调整,其范围在1~MAX_RT_PRIO-1间。默认MAX_RT_PRIO配置为100,即默认的实时优先级范围是1~99, 数值越高优先级越高。而nice值(-20 — 20),影响的是普通进程优先级。

系统调度时,实时优先级高的进程总是先于优先级低的进程执行(不管他们采用的是FIFO还是RR调度策略)。如果有数个优先级相同的实时进程,那么系统就会按照SCHED_FIFO或SCHED_RR选择进程。假设当前CPU运行的实时进程A的优先级为a,而此时有个优先级为b的实时进程B进入可运行状态,那么只要b>a,系统将中断A的执行,而优先执行B,直到B无法执行(无论A,B为何种实时进程)。

相同优先级的调度策略:

  • SCHED_FIFO:先入先出调度策略(First in-first out scheduling)。该策略简单的说就是一旦进程占用cpu则一直运行,一直运行直到有更高优先级任务到达或自己放弃。

  • SCHED_RR:时间片轮转调度(Round-robin scheduling)。给每个线程增加了一个时间片限制,当时间片用完后,系统将把该线程置于队列末尾,然后运行其他相同优先级的进程,如果没有其他相同优先级的进程,则该进程会继续执行(前提是没有其他更高优先及进程)。 高优先级运行期间,低优先级没法抢占(即使时间片用完),只能等到高优先级主动退出。

只有在下述事件之一发生时,实时进程才会被另外一个进程取代。

(1)进程被另外一个具有更高实时优先级的实时进程抢占。

(2)进程执行了阻塞操作并进入睡眠

(3)进程停止(处于TASK_STOPPED 或TASK_TRACED状态)或被杀死。

(4)进程通过调用系统调用sched_yield(),自愿放弃CPU 。

(5)进程基于时间片轮转的实时进程(SCHED_RR),而且用完了它的时间片。

实时线程优先级高于所有普通线程,如果有实时线程处于运行态,则系统调度时一定会选择调用实时线程;正在运行的实时线程只会被拥有更高实时优先级的线程抢占。所以在应用中如果需要将某个线程设置为实时线程,则需要用户自己确保该线程不会处于忙执行而完全占用CPU资源,导致其他普通线程没法获得CPU资源而一直被阻塞得不到执行,并且需要合理给予优先级的值,太高有可能会影响重要系统线程的运行。所有用户态线程默认没有实时优先级,都属于普通线程。

2. 普通进程优先级(非实时、动态优先级,SCHED_OTHER(SCHED_NORMAL))

系统创建线程时,默认的线程是SCHED_OTHER。所以如果我们要改变线程的调度策略的话,可以通过下面的这个函数实现。

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

普通进程的静态优先级只能是0,但可以通过nice值来改变其优先级。

nice值的范围是-20~19,nice数值越大就使得static_prio越大,最终进程优先级就越低。

系统调度时,还会考虑其他因素,因而会以nice为基础计算出进程动态优先级,根据此来实施调度。因为,不仅要考虑优先级,也要考虑进程的属性。例如如果进程属于交互式进程,那么可以适当的调高它的优先级,使得界面反应地更加迅速,从而使用户得到更好的体验。

进程的时间片就是完全依赖nice值来分配,低nice值的进程拥有更长的时间片。

系统会严格按照动态优先级高低的顺序安排进程执行。动态优先级高的进程进入非运行状态,或者时间片消耗完毕才会轮到动态优先级较低的进程执行。动态优先级的计算主要考虑两个因素:静态优先级,进程的平均睡眠时间。

  • SCHED_NORMAL(SCHED_OTHER):该策略是是默认的Linux分时调度(time-sharing scheduling)策略,它是Linux线程默认的调度策略。

其实,普通进程的调度,是CPU根据进程优先级算出时间片,这样并不能一定保证高优先级的进程一定先运行,只不过和优先级低的进程相比,通常优先级较高的进程获得的CPU时间片会更长而已。其实,如果要想保证一个线程运行完在运行另一个线程的话,就要使用多线程的同步技术,信号量,条件变量等方法。而不是绝对依靠优先级的高低,来保证。

3. CFS

linux在2.6.23内核中采用的是“完全公平调度算法”简称CFS,来取代传统的非实时进程的SCHED_NORMAL调度算法。

传统调度策略必须规定一个默认的时间片,但是CFS没有直接分配时间片给进程,而是将处理器的使用比例(权重)给进程,这个比例(权重)根据所有进程的总nice和自身nice值来计算。

如有三个进程,A nice为5,B nice为5,则A权重为1/2,B为1/2。假设总CPU时间为10ms,则A能运行5ms,B也5ms。

另外A能运行5ms不代表A会运行5ms,A有可能执行了1ms后就完成了任务然后就放弃CPU,也有可能一直运行5ms还没能完成任务。

另外这个应得的cpu时间不应太小(假设阈值为1ms),否则会因为切换得不偿失。但是,当进程足够多时候,肯定有很多不同权重的进程获得相同的时间——最低阈值1ms,所以,CFS只是近似完全公平。

CFS允许每个进程运行一段时间,循环轮转,选择运行时间最少的那个进程作为下一个运行进程,即一段时间内运行时间最少的进程拥有高优先级。CFS不再依据nice作为优先级而进行调度,但是依然会用到nice值计算权重。

4. 系统何时会调用schedule()函数

  • 进程从中断,异常,系统调用返回用户态的时候,系统调用 do_fork()函数

  • 定时中断,当前进程的时间片用完,  do_timer()函数

  • 进程状态切换的时候,进程终止,进程唤醒等,进程调用sleep() exit()等函数,唤醒进程 wake_up_process()函数

  • 改变进程的调度策略:setscheduler()函数

  • 系统调用礼让:sys_sched_yield()函数

5. 优先级和时间片

  • 优先级,高优先级的进程总是会抢占低优先级的进程执行,无论该低优先级进程的时间片是否已经用完;相同优先级按轮询调度。

  • 时间片,相同优先级的进程A和B,如果A在运行,只有当A的时间片用完或者A主动休眠放弃CPU,B才有机会被执行。

  • 只有SCHED_RR和SCHED_NORMAL调度有时间片的概念

6. 总结

  • Linux 标准内核实现两个调度类:采用 CFS 调度算法的默认调度类和实时调度类

  • Linux的调度策略区分实时进程和普通进程,实时进程的调度策略是SCHED_FIFO和SCHED_RR,普通的非实时进程的调度策略是SCHED_NORMAL(SCHED_OTHER)。

  • CFS:取代了SCHED_NORMAL(SCHED_OTHER), CFS 不采用严格规则来为一个优先级分配某个长度的时间片,而是为每个进程分配一定比例的 CPU 处理时间(权重)进行调度

  • 实时调度类:SCHED_FIFO或SCHED_RR调度策略,静态优先级。

Linux进程调度策略分析相关推荐

  1. 第一次作业:基于Linux进程模型分析

    1.Linux是如何组织进程的. *进程的概念:进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算 ...

  2. Linux进程调度策略的发展和演变--Linux进程的管理与调度(十六)

    日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.6 X86 & arm gatieme LinuxDeviceDrivers Linux进程管理与调度 ...

  3. linux 进程内存分析工具,Linux内存使用情况以及内存泄露分析之工具与方法

    1. 内存使用情况分析 1.1 系统总内存分析 通过cat /proc/meminfo,可用的物理内存=MemFree+Buffers+Cached. MemTotal:        5933132 ...

  4. Linux进程调度策略有哪几种,Red Hat Enterprise Linux 8的9种实时进程调度策略

    Red Hat Enterprise Linux 8的9种实时进程调度策略 Red Hat Enterprise Linux 8使用是Linux内核版本是Kernel 4.18,其系统进程的实时调度策 ...

  5. Linux进程的分析和执行过程

    摘自:http://jingshengsun888.blog.51cto.com/1767811/1242215 一 分析 1 分析工具 strace -p 进程号 每一行都是一条系统调用,等号左边是 ...

  6. Linux 进程调度策略

    目录 进程分类 进程抢占 调度算法和调度类 普通进程的调度 基础时间片的计算 动态优先级和平均睡眠时间 实时进程调度 同优先级FIFO RR并存 进程分类 有两种传统的分类法: 方法一 CPU密集 I ...

  7. linux进程调度策略和优先,linux进程调度之FIFO和RR调度策略

    严格地说,对于优先级对于实时进程和普通进程的意义是不一样的. 1.在一定程度上,实时进程优先级高,实时进程存在,就没有普通进程占用CPU的机会,(但是前一篇博文也讲过了,实时组调度出现在内核以后,允许 ...

  8. linux进程 crash 分析工具,crash工具分析大型Linux服务器死锁实战

    Linux服务器背景: CPUS: 40 MEMORY: 127.6 GB MACHINE: x86_64 (2199 Mhz) Linux Kernel: 4.4.121 TASKS: 19411 ...

  9. Linux进程内存分析pmap命令

    名称:        pmap - report memory map of a process(查看进程的内存映像信息)pmap命令用于报告进程的内存映射关系,是Linux调试及运维一个很好的工具. ...

最新文章

  1. [转] React 是什么
  2. mysql.cnf utf8_mysql通过my.cnf修改默认字符集为utf-8的方法和注意事项
  3. 分类型变量预测连续型变量_终于弄清楚java的变量与类型了!
  4. 黑客宣称掌握了600多万个Instagram账号的信息
  5. 知乎高赞:自控力极差的人如何自救?
  6. 大数据之旅--Hadoop的发展史
  7. 算法稳定币项目Basis Cash将于2月7日启动V2迁移计划
  8. [转载]测试程序执行时间
  9. python进阶(一)关联sql的算法操作
  10. 基于 HTML5 WebGL 的挖掘机 3D 可视化应用
  11. linux crontab怎么启动,【linux之crontab,启动】(示例代码)
  12. ESP32 开发笔记(四)LVGL控件学习 Roller 滑动选择控件
  13. Visual Studio MFC编程 程序调试时所遇到的问题及解决方法
  14. 倒残差与线性瓶颈浅析 - MobileNetV2
  15. 基于FPGA的视频处理
  16. 咖啡,为什么有些比较甜?
  17. Excel怎么一次性删除数据末尾的空格
  18. 一个老程序员的一些职场经验分享
  19. 2016 GitHub章鱼猫观察报告之开源统计
  20. 2023年【福建省安全员C证(专职安全员)】考试及福建省安全员C证(专职安全员)试题及解析

热门文章

  1. C#中搜索关键词高亮显示
  2. Asp.net MVC 示例项目Suteki.Shop分析之---ViewData
  3. Windows Server Core管理之WinRM
  4. 给Vista系统加入一键还原功能
  5. js Date 对象用于处理日期和时间。
  6. js中call与apply用法
  7. tomcat 、jsp、 servlet 、jstl版本对应
  8. 单点登录(SSO)—简介 1
  9. php 不是有效的win32,%1不是有效的 win32应用程序(64位转换32位)
  10. scrapy 搜索关键字_Scrapy 新浪微博搜索爬虫