聊聊Linux内核进程调度上篇

linux的进程调度器是内核中最关键的组件之一,它负责决定何时以及多久一个进程可以获得cpu时间。在最理想的情况下,进程调度器需要确保每个进程都能合理地分配到cpu执行指令的时间。为此,进程调度器必须具备以下特性:

聊聊Linux内核进程调度上篇

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

聊聊Linux内核进程调度上篇

码上飞 码上飞

码上飞(CodeFlying) 是一款AI自动化开发平台,通过自然语言描述即可自动生成完整应用程序。

码上飞 138 查看详情 码上飞

内核中的运行队列包含了所有进程,每个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();}

以上就是聊聊Linux内核进程调度上篇的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/470365.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
Mac电脑玩《Billiard Wear》攻略,如何在苹果电脑上运行这款iOS游戏?
上一篇 2025年11月8日 07:15:26
Java函数式编程中递归式分治算法的技巧
下一篇 2025年11月8日 07:15:31

相关推荐

发表回复

登录后才能评论
关注微信