cfs调度算法JAVA实现_CFS调度算法的思想和细节

今天在邮件列表里面有位朋友问了一个问题,问题表述如下:在唤醒进程的时候,发现在check_preempt_wakeup()中.会将 cfs_rq->next设置为唤醒的进程,cfs_rq->last设置为当前的运行进程.然后将要唤醒的进程重新入列,即 enqueue_task().在pick_next_task_fair()中选择下一个调度进程的时候,有这样的选择 pick_next_...
摘要由CSDN通过智能技术生成

今天在邮件列表里面有位朋友问了一个问题,问题表述如下:

在唤醒进程的时候,发现在check_preempt_wakeup()中.会将 cfs_rq->next设置为唤醒的进程,cfs_rq->last设置为当前的运行进程.然后将要唤醒的进程重新入列,即 enqueue_task().在pick_next_task_fair()中选择下一个调度进程的时候,有这样的选择 pick_next_task_fair() ---> pick_next_entity():

static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq)

{

struct sched_entity *se = __pick_next_entity(cfs_rq);

if (cfs_rq->next && wakeup_preempt_entity(cfs_rq->next, se) < 1)

return cfs_rq->next;

if (cfs_rq->last && wakeup_preempt_entity(cfs_rq->last, se) < 1)

return cfs_rq->last;

return se;

}

其 中__pick_next_entity()用来选择rb_tree中最左端的se.然后,再调用wakeup_preempt_entity()来判断 选择出的se是否可以抢占cfs_rq->next和cfs_rq->last.现在我的疑问是: cfs_rq->next和cfs_rq->last是拿来做什么的呢? 它是为了保证唤醒时的当前进程和被唤醒的进程优先运行吗?但是,唤醒进程的时候已经调整了它的vruntime,并且调用enqueue_task()入 列,这样,它在选择下一个进程的时候,为什么直接按照vruntime值来调度呢?

之所以有这样的疑问就是因为这位朋友没有从全局去考虑和理解cfs调度算法,而迷失在了局部的代码细节,这在读linux源代码的时候是一大 忌,linux的设计思想是很好很模块化很清晰的,但是具体到代码细节就不是这么美好了,这其实是一个编程习惯问题而不是什么设计问题。解决上述的问题很 容易,其实只要找一下check_preempt_wakeup的调用点就会发现,并不是仅仅在唤醒进程的时候才调用的,比如在更改进程优先级或者创建新 进程或者迁移进程的时候都要调用它。要点就是,如果入队的时候没有更新vruntime,那么就有必要将pick_up_next的结果也就是红黑树最左 下的结点和新入队的做一番比较,因为入队时的情况是不确定的,如果没有更新入队进程的vruntime但是其权值已经改变或者绑定的运行处理器已经改变的 话,比如迁移进一个新cpu的运行队列,那么就不能用它保留的原来的vruntime来竞争cpu了,但是又不想破坏代码的简洁而重新每次都在入队时计算 vruntime,那么只有先保留一个cfsq->next字段用来记录这个需要仲裁的新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值