Linux调度CFS源码分析(一) 预备知识

源码分析版本:4.12

curl Index of /pub/linux/kernel/v4.x/linux-4.12.14.tar.xz -o linux-4.12.14.tar.xz

git clone -b v4.12 --depth 1 GitHub - torvalds/linux: Linux kernel source tree linux-4.12

/home/xxxxin4/sdc/linux-4.12.14

  1. 新创建进程和线程系统调度做了哪些事情
  2. 在用户空间中调用了一个系统调用接口,调度程序做了哪些事情,以申请内存接口brk为例进行分析
  3. setpriority和nice这两个用户接口如何影响用户调度的,类似接口sched_setscheduler

/frameworks/base/core/java/android/os/Process.java#1026

  1. 其他影响调度的方法哪些,原理是什么
  2. 负载均衡什么时候进行,被迁移的进程需要符合哪些条件
  3. 调度的开销计算在哪里?
  4. 如何结合场景信息,平衡好吞吐量和响应速度之间的矛盾;优化显示链路调度流程的思考

线程调度相关的预备知识

  • 从内存角度看进程和线程

静态的来看,进程和线程就是内核里面的一堆资源相关的数据结构(内存),见struct task_struct。task_struct既是线程又是进程的代理(不是进程或者线程本身)。

  • (struct task_struct *)当前进程的进程句柄保存在sp_el0,可以用过get_current来获取。
  • 进程状态变迁

    1. 就绪状态:进程描述符的字段state是TASK_RUNNING(Linux内核没有严格区分就绪状态和运行状态),正在运行队列中等待调度器调度。
    2. 运行状态:进程描述符的字段state是TASK_RUNNING,被调度器选中,正在处理器上运行。
    3. 轻度睡眠:也称为可打断的睡眠状态,进程描述符的字段state是TASK_INTERRUPTIBLE,可以被信号打断。
    4. 中度睡眠:进程描述符的字段state是TASK_KILLABLE,只能被致命的信号打断。
    5. 深度睡眠:也称为不可打断的睡眠状态,进程描述符的字段state是TASK_UNINTERRUPTIBLE,不能被信号打断。
    6. 僵尸状态:进程描述符的字段state是TASK_DEAD,字段exit_state是EXIT_ZOMBIE。如果父进程关注子进程退出事件,那么子进程在退出时发送SIGCHLD信号通知父进程,变成僵尸进程,父进程在查询子进程的终止原因以后回收子进程的进程描述符。
    7. 死亡状态:进程描述符的字段state是TASKDEAD,字段exitstate是EXITDEAD。如果父进程不关注子进程退出事件,那么子进程退出时自动消亡。
  • 调度是CPU资源管理器。所有进程运行都需要CPU,对CPU进行时间分割的具体做法就叫进程调度。
    1. 为什么要调度:为了实现多任务并发;当前Android使用抢占式多任务,能够保证内核对CPU资源的合理分配,抢占式调度触发调度和执行调度是分离的。
    2. 为什么能调度:因为用户空间是可切换的,线程栈是可切换的。

  • 19
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Linux内核进程调度是一个非常复杂的系统,主要由可调度进程队列、进程调度策略、调度器负责。 在Linux中,进程调度器是一个单独的内核线程,其主要工作是在可调度进程队列中选择下一个要运行的进程,并将CPU分配给该进程。进程调度器根据进程的优先级和调度策略来选择下一个要运行的进程。 Linux中进程调度的核心代码位于sched目录下,主要包括以下文件: 1. sched.h:定义了调度器的数据结构和函数原型。 2. sched.c:实现了进程调度器的主要功能,包括进程的加入、删除、更新等操作。 3. rt.c:实时调度策略相关代码。 4. fair.c:CFS调度策略相关代码。 5. idle.c:空闲进程相关代码。 6. deadline.c:DEADLINE调度策略相关代码。 下面我们以CFS调度策略为例,简单介绍一下进程调度的实现过程: CFS调度策略是一种完全公平的调度策略,它通过动态优先级来保证进程的公平性。在CFS调度策略中,每个进程都有一个虚拟运行时间(virtual runtime),该时间是进程已经运行的时间和优先级的函数。 CFS调度策略的核心代码位于fair.c文件中,主要包括以下函数: 1. enqueue_task_fair():将一个进程添加到可调度进程队列中。 2. dequeue_task_fair():将一个进程从可调度进程队列中删除。 3. update_curr_fair():更新当前进程的虚拟运行时间。 4. pick_next_task_fair():选择下一个要运行的进程。 以上函数的实现过程中,都涉及到了对进程调度器的数据结构的操作,如可调度进程队列、进程控制块等。具体实现过程需要结合代码进行分析。 总体来说,Linux内核进程调度的实现非常复杂,需要涉及到很多的数据结构和算法,同时还需要考虑到性能、公平性等因素。因此,对于想要深入了解Linux内核的人来说,进程调度是必须要掌握的一个重要部分。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值