array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 《深入理解Linux内核》--第七章:进程调度:读书笔记 - 爱码网

零、感想
进程调度涉及的 priority、进程的状态(TASK_RUNNING、TASK_INTERRUPT、TASK_UNINTERRUPT、TASK_STOPPED)。Linux系统有个PID为0的进程——swapper进程(只有在CPU不能执行其他进程才执行)。
在多处理器系统中涉及 调度域,比较值得注意的是Intel的超线程技术包括几个内部寄存器的拷贝,当前线程在访问内存的间隙时,处理器可以使用它的机器周期去执行另一个线程),因为超线程技术,引入了逻辑CPu和物理CPU的概念,在一个物理CPU中可以有两个逻辑CPU(超线程所致);超线程中又带来一个注意点就是:当调度程序检查其他CPU空闲与否时,调度程序需要判断物理CPU是否有空,如果仅仅是超线程CPU的一个逻辑CPU空闲而另一个忙碌则不能将其它CPU上待运行的进程调度该物理CPU上。
在多处理器系统中,如果被迁移的进程已经在远程CPU的 Cache中(高速缓存命中),那么不应该迁移该进程到其他CPU上去执行,因为已经在远程CPU上可能Cache中的数据和RAM中的数据不一致,需要等待期写回。
比较重要的数据结构:runqueue(运行队列)
比较重要的函数:schedule()进程调度函数 。

一、单核调度策略及数据结构和函数
进程一种分类:I/O受限(I/O-bound)、CPU受限(CPU-bound)
进程另一种分类:交互式(Interactive)经常与用户进行交互、
批处理(batch)不必与用户交互,经常在后台运行、
实时(real-time)要很短的相应时间,而且响应时间的变化应该小
交互式进程相对有较高的优先级,不管时间片多长,都会很快抢占批处理进程。
如果进程进入TASK_RUNNING状态,内核检查它的动态优先级是否大于当前运行进程的优先级。
1)调度算法
调度类型:a)SCHED_FIFO,如果没有比当前优先级高(不包括同级)的进程则一直使用CPU直到
放弃 。 CPU调度室,将进程描述符放在运行队列链表的当前位置
b)SCHED_RR,时间片轮转,CPU调度时,将进程描述符放在运行队列链表的末尾。
c)SCHED_NORMAL,普通分时
基本时间片(ms)= a】 (140-静态优先级)*20, 静态优先级<120
b】 (140-静态优先级)*5, 静态优先级>=120
动态优先级=max{100,min【静态优先级-bonus+5,139】}
bonus:0~10,<5表示降低动态优先级以表示惩罚,>5表示升高优先级表奖赏。
bonus-5>=静态优先级/4-28
活动和过期进程:a】活动进程,还没有用完他们的时间片,运行它们运行
b】过期进程,这些可运行(TASK_RUNNING)进程用完了它们的时间片,被禁止
运行,直到所有活动进程都过期,才恢复运行。
注意:一般复杂些,用完其时间片的交互式进程通常仍然是活动进程。实
时进程总是
被当做活动进程

2)数据结构
runqueue运行队列(存放在runqueues的Per-CPU变量中):
系统中每个可运行进程属于且只属于一个运行队列。
array字段:包含两个prio_array_t结构数组。
每个prio_array_t数据结构都表示一个可运行进程集合: 包括140个双向链表头(每
个链表对应一个可能的进程优先级0~139)
,一个优先级位图, 一个可运行进程集合的
进程数量的计数器。
《深入理解Linux内核》--第七章:进程调度:读书笔记
进程描述符
thread_info->cpu:可运行进程所在队列的逻辑CPU号(注意是threa,所以是线程级的
CPU逻辑号)

time_slice:进程时间片中海剩余的时钟节拍数。
p->time_slice=(current->time_slice+1)>>1;
curent->time_slice>>=1;(如果当前为1,则子进程为1,自己为0,父爱伟大)
父进程创建子进程是,time_slice划分为两等分,一份给父进程,一份给子进程。
(避免无限获得CPU时间:父进程创建一个运行相同代码的子进程,并随后杀死自
己,通过适当调节创建速度,子进程总是在父进程过期之前获得新的时间片)
3)函数
scheduler_tick()维持当前最新的time_slice计数器
try_to_wake_up()唤醒随眠进程
将进程状态设置为TAK_RUNNING,然后把进程插入到本地CPU的运顶队列
recalc_task_prio()更新动态优先级 和平均睡眠时间
schedule()选择要被执行的新进程
在运行队列的链表中找到一个进程,将CPU分配给这个进程.
如果进程current设置了TIF_NEED_RESCHED为1,则需要调用schedule()
load_balance()维持多处理器系统中运行队列平衡

二、多处理系统中运行队列平衡
多处理涉及体系结构:a】标准的多处理器体系结构:共有的RAM被所有CPU共享
b】超线程:包括几个内部寄存器的拷贝,当前线程在访问内存的间隙时,处理
器可以使用它的机器周期去执行另一个线程.
c】NUMA:CPU和RAm以本地“节点”为单位分组。内存仲裁器是多处理器系
统的性能瓶颈。本地CPU访问远程RAM比较慢。
(这样一个保持可运行状态的进程通常限制在一个固定CPU上)
调度域:一个CPU集合。最上层的调度域包括多个子调度域,每个子调度域包括一个CPU子集。
《深入理解Linux内核》--第七章:进程调度:读书笔记
函数:
rebalance_tick():
load_balance()
move_task()

三、调度使用的函数:
nice()系统调用:允许进程改变它们基本优先级。
getpriority(),setpriority()
sched_getaffinity(), sched_setaffinity()

英文含义:
Schedule Policy调度策略
time sharing 时分
NUMA (Non-Uniform Memory Access)非一致内存访问
RR(Round-robin),轮转
Schedule domain 调度域

相关文章: