对sleep(0)和sched_yield一点理解

在了解sleep(0)和sched_yield之前先让我们看看linux是怎么调度的(这里只讲CFS)

1.CFS

CFS不会根据优先级分配一个不变的运行时间,比如说分配5ms这样的,它是一个分配占用处理器比例的一个分配算法。CFS的做法是允许每个进程运行一段时间,循环轮转,选择运行最少的进程(通过vruntime来判断,下面可以看到vruntime是怎么计算的)作为下一个运行进程,而不再采用分配给每个进程时间片的做法了。CFS在所有可运行进程总数基础上计算出一个进程应该运行多久,而不是依靠nice值来计算时间片。nice值在CFS中被作为进程获得的处理器运行比的权重:越高的nice值(越低的优先级)进程获得更低的处理器使用权重,这是相对默认nice值进程的进程而言的。相反,更低的nice值(越高的优先级)的进程获得更高的处理器使用权重。

CFS调度器的一个调度周期值是固定的,由sysctl_sched_latency变量保存。

一个进程在一个调度周期中的运行时间为:         

分配给进程的运行时间 = 调度周期*进程权重/所有进程权重之和

从上面可以看到一个进程的优先级越高(权重越大,分到的运行时间越多)。

一个进程的实际运行时间和虚拟运行时间之间的关系为

vruntime = 实际运行时间*NICE_0_LOAD / 进程权重
         = 实际运行时间*1024 / 进程权重

从上面可以看到,进程的权重越大,vruntime增长的越慢。比如说,进程的权重为1024的进程,运行时间为1时,vruntime为1。再看看进程权重为512的进程,运行时间为0.5时,vruntime就为1了。(在这里可以理解CFS根据vruntime来调度进程运行了)

一个进程在一个调度周期内分配到的虚拟运行时间大小为:

vruntime = 进程在一个调度周期内的实际运行时间*1024 / 进程权重
         = (调度周期 * 进程权重 / 所有进程总权重) * 1024 / 进程权重
         = 调度周期*1024 / 所有进程总权重

可以看到一个进程在一个调度周期内分配到的vruntime值大小都是一样的

上面的分析是引用的https://blog.csdn.net/liuxiaowu19911121/article/details/47070111

 

2.三个队列:运行队列,过期队列,等待队列

1.等待队列:休眠(或者阻塞)的进程放在等待队列里面,进程的状态为TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE

2.运行队列:这些进程还没有用完时间片,因此允许它们运行。

3.过期队列:时间片运行完的进程放在这个队列,这里面的进程不能被调度运行,除非所有的进程都运行完了自己的时间片。

 

3.sleep(n),sleep(0),sched_yield

sleep(n):把进程状态设为TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE,然后在放入等待队列中。当睡眠的时间足够了之后再放入运行队列中(注意有可能被唤醒之后就能执行也有可能过一段时间才能执行)

sleep(0):让CPU在根据调度程序去调度,如果存在vruntime比它小的就让那个进程运行,如果不存在就自己继续运行

sched_yield:sched_yield把自己放入过期队列中,所以需要等所有的进程过期之后才有可能运行

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值