暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

聊聊Linux内核进程调度上篇

325


作者时间QQ技术交流群
perrynzhou@gmail.com2022/05/01672152841




基本介绍

  • Linux的进程调度器是内核中最重要的核心组件,它决定了一个进程合适获取CPU的时间以及占用CPU的时间。最佳情况下每个进程需要CPU执行指令的时间,如果需要保证进程之间的如何合理的分配CPU的指令执行时,进程的调度器需要具备如下的特性.



  • Linux进程调度器采用类似于vfs
    的设计采用简单的两层结构模式,第一层是通用调度器,定义作为进程调度器的入口抽象层;第二层是调度器的具体实现,根据调度策略实现进程的调度的器的具体实现。第一层的使用了struct sched_class
    来描;第二层是具体的具体的调度器包括deadline调度器(struct sched_class dl_sched_class)
    实时调度器(struct sched_class rt_sched_class)
    完全公平调度器(struct sched_class fair_sched_class)

  • 内核中运行队列包含了所有的进程,每个CPU都有一个运行队列,各自的进程运行队列都会在各自的CPU队列争夺CPU的运行时间。实际的进程调度器都会嵌入到每个CPU的运行队列中。内核中进程运行队列是通过struct rq
    来定义


// 省略大部分字段,着重描述下运行队列中的一些字段
struct rq {
// 每个CPU的运行队列的锁
raw_spinlock_t lock;
// 运行队列的进程数
unsigned int nr_running;
// 当前CPU上的负载
struct load_weight load;
// 进程切换的次数
u64 nr_switches;
// 公平调度器
struct cfs_rq cfs;
// 实时调度器
struct rt_rq rt;
// deadline调度器
struct dl_rq dl;

unsigned long nr_uninterruptible;
// 正在运行的进程任务
struct task_struct *curr;
// 空闲的进程任务
struct task_struct *idle;
// 停止的进程任务
struct task_struct *stop;
unsigned long next_balance;
};


进程调度实现

  • 进程调度是调用进程第一层的通用调度器,内核是从__schedule()
    函数开始,该函数是挑选下一个最佳的可运行的进程任务。__schedule()
    函数中的pick_next_task()
    遍历实际调度器中的函数,并选择出下一个最佳的任务。如果其他实际调度器没有更高的优先级可运行的进程任务,则pick_next_task()
    会选择完全公平调度器
    中寻找下一个进程任务。


static void __sched notrace __schedule(bool preempt)
{
next = pick_next_task(rq, prev, &rf);
}
// 选择一个优先级最高的进程执行
static inline struct task_struct *pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
{
const struct sched_class *class;
struct task_struct *p;


if (likely((prev->sched_class == &idle_sched_class ||
prev->sched_class == &fair_sched_class) &&
rq->nr_running == rq->cfs.h_nr_running)) {

p = fair_sched_class.pick_next_task(rq, prev, rf);
if (unlikely(p == RETRY_TASK))
goto again;

if (unlikely(!p))
p = idle_sched_class.pick_next_task(rq, prev, rf);

return p;
}

again:
for_each_class(class) {
p = class->pick_next_task(rq, prev, rf);
if (p) {
if (unlikely(p == RETRY_TASK))
goto again;
return p;
}
}

BUG();
}


文章转载自存储内核技术交流,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论