建设教育网站的目的,wordpress每次都要ftp,个人建立网站后怎么盈利,如果让你建设网站之前你会想什么CFS(完全公平调度器)是Linux内核2.6.23版本开始采用的进程调度器#xff0c;它的基本原理是这样的#xff1a;设定一个调度周期(sched_latency_ns)#xff0c;目标是让每个进程在这个周期内至少有机会运行一次#xff0c;换一种说法就是每个进程等待CPU的时间最长不超过这个…CFS(完全公平调度器)是Linux内核2.6.23版本开始采用的进程调度器它的基本原理是这样的设定一个调度周期(sched_latency_ns)目标是让每个进程在这个周期内至少有机会运行一次换一种说法就是每个进程等待CPU的时间最长不超过这个调度周期。然后根据进程的数量大家平分调度周期内的CPU使用权。由于进程的优先级即nice值不同分割调度周期的时候要加权。每个进程的累计运行时间保存在自己的vruntime字段里哪个进程的vruntime最小就获得本轮运行的权利。那么问题就来了新进程的vruntime的初值是不是0假如新进程的vruntime初值为0的话比老进程的值小很多那么它在相当长的时间内都会保持抢占CPU的优势老进程就要饿死了这显然是不公平的。所以CFS是这样做的每个CPU的运行队列cfs_rq都维护一个min_vruntime字段记录该运行队列中所有进程的vruntime最小值新进程的初始vruntime值就以它所在运行队列的min_vruntime为基础来设置与老进程保持在合理的差距范围内。fork出来的新进程的vruntime初值的设置与两个参数有关sched_child_runs_first规定fork之后让子进程先于父进程运行;sched_features的START_DEBIT位规定新进程的第一次运行要有延迟。sched_features是控制调度器特性的开关每个bit表示调度器的一个特性。在sched_features.h文件中记录了全部的特性。START_DEBIT是其中之一如果打开这个特性表示给新进程的vruntime初始值要设置得比默认值更大一些这样会推迟它的运行时间以防进程通过不停的fork来获得cpu时间片。如果参数 sched_child_runs_first打开意味着创建子进程后保证子进程会在父进程之前运行。子进程在创建时vruntime初值首先被设置为min_vruntime然后如果sched_features中设置了START_DEBIT位vruntime会在min_vruntime的基础上再增大一些。设置完子进程的vruntime之后检查sched_child_runs_first参数如果为1的话就比较父进程和子进程的vruntime若是父进程的vruntime更小就对换父、子进程的vruntime这样就保证了子进程会在父进程之前运行。休眠进程的vruntime一直保持不变吗如果休眠进程的 vruntime 保持不变而其他运行进程的 vruntime 一直在推进那么等到休眠进程终于唤醒的时候它的vruntime比别人小很多会使它获得长时间抢占CPU的优势其他进程就要饿死了。这显然是另一种形式的不公平。CFS是这样做的在休眠进程被唤醒时重新设置vruntime值以min_vruntime值为基础给予一定的补偿但不能补偿太多。休眠进程在唤醒时会立刻抢占CPU吗这是由CFS的唤醒抢占特性决定的即sched_features的WAKEUP_PREEMPT位。由于休眠进程在唤醒时会获得vruntime的补偿所以它在醒来的时候有能力抢占CPU是大概率事件这也是CFS调度算法的本意即保证交互式进程的响应速度因为交互式进程等待用户输入会频繁休眠。除了交互式进程以外主动休眠的进程同样也会在唤醒时获得补偿例如通过调用sleep()、nanosleep()的方式定时醒来完成特定任务这类进程往往并不要求快速响应但是CFS不会把它们与交互式进程区分开来它们同样也会在每次唤醒时获得vruntime补偿这有可能会导致其它更重要的应用进程被抢占有损整体性能。案例说明我曾经处理过一个案例服务器上有两类应用进程A进程定时循环检查有没有新任务如果有的话就简单预处理后通知B进程然后调用nanosleep()主动休眠醒来后再重复下一个循环B进程负责数据运算是CPU消耗型的B进程的运行时间很长而A进程每次运行时间都很短但睡眠/唤醒却十分频繁每次唤醒就会抢占B导致B的运行频繁被打断大量的进程切换带来很大的开销整体性能下降很厉害。那有什么办法吗有最后我们通过禁止CFS唤醒抢占 特性解决了问题# echo NO_WAKEUP_PREEMPT /sys/kernel/debug/sched_features禁用唤醒抢占特性之后刚唤醒的进程不会立即抢占运行中的进程而是要等到运行进程用完时间片之后。在以上案例中经过这样的调整之后B进程被抢占的频率大大降低了整体性能得到了改善。进程从一个CPU迁移到另一个CPU上的时候vruntime会不会变# grep min_vruntime /proc/sched_debug.min_vruntime : 12403175.972743.min_vruntime : 14422108.528121如果一个进程从min_vruntime更小的CPU (A) 上迁移到min_vruntime更大的CPU (B) 上可能就会占便宜了因为CPU (B) 的运行队列中进程的vruntime普遍比较大迁移过来的进程就会获得更多的CPU时间片。这显然不太公平。CFS是这样做的当进程从一个CPU的运行队列中出来 (dequeue_entity) 的时候它的vruntime要减去队列的min_vruntime值而当进程加入另一个CPU的运行队列 ( enqueue_entiry) 时它的vruntime要加上该队列的min_vruntime值。这样进程从一个CPU迁移到另一个CPU之后vruntime保持相对公平。