您的位置:首页 > 运维架构 > Shell

shell学习五十五天----进程记账

2015-07-29 14:48 656 查看
linux进程调度的实现----进程记账

linux进程调度的实现一共由四部分组成:

1.时间记账(就是记录进程已经运行了多长时间,还要运行多长时间)

2.进程选择(加入红黑树)

3.调度器入口

4.睡眠和唤醒



进程记账:就是记录一个进程占用处理器资源的时间长度.既然要记录,那么就需要存在在一个位置,内核说,放在sched_entity结构中吧.我们当然要听内核的....



至于sched_entity这个结构的源码我就不贴了,但是里面有一个vruntime成员变量,这个成员变量可看成virtual run time,正确名字是虚拟实时.

这个vruntime变量就是用来记录进程已经运行的时间长短,或者说,占用处理器已经多长时间了.那么这个事件越长就越证明运行的时间越长,就越容易被其他的进程挤掉,也就是,其他进程容易抢占进来.linux系统对于进城的调度室要看这个变量来采取行动的.那么这个虚拟实时(时间值)怎么计算出来的?(这个计算过程就是进程记账的过程),内核使用update_curr()函数来实现这个过程.源码:

static void update_curr(struct cfs_rq *cfs_rq)

{

struct <span style="color:#FF0000;">sched_entity *curr</span> = cfs_rq->curr;

u64 <span style="color:#FF0000;">now</span> = rq_of(cfs_rq)->clock_task;

unsigned long <span style="color:#FF0000;">delta_exec</span>;



if (unlikely(!curr))

return;



/*

* Get the amount of time the current task was running

* since the last time we changed load (this cannot

* overflow on 32 bits):

*/

<span style="color:#FF0000;"> delta_exec = (unsigned long)(now - curr->exec_start);</span>

if (!delta_exec)

return;



<span style="color:#FF0000;">__update_curr(cfs_rq, curr, delta_exec);</span>

curr->exec_start = now;



if (entity_is_task(curr)) {

struct task_struct *curtask = task_of(curr);



trace_sched_stat_runtime(curtask, delta_exec, curr->vruntime);

cpuacct_charge(curtask, delta_exec);

account_group_exec_runtime(curtask, delta_exec);

}



account_cfs_rq_runtime(cfs_rq, delta_exec);

}



这个update_curr函数中存在这么几个变量和函数.curr是一个sched_entity结构指针,接收函数传进的参数.函数参数那个结构是什么?搞不明白,反正就是吧其中的一个成员复制curr变量.看名字可以知道是指进程当前的状态(当然,包括虚拟实时).接着定义了一个无符号长整型变量delta_exec,查一下delta有增量的意思,而exec是执行,那么从名字上看就是值执行的增量(就是时间的增量).然后,看到delta_exec被赋值为now和exec_start的差值,exec_start这个可以知道这时开始,现在减开始的,那就是已经运行的时间.最后执行__update_curr函数将当前的进程账本,和已经运行的时间作为参数传如,先来看一下__update_curr()这个函数:

static inline void

__update_curr(struct cfs_rq *cfs_rq, struct <span style="color:#FF0000;">sched_entity *curr</span>,

unsigned long <span style="color:#FF0000;">delta_exec</span>)

{

unsigned long delta_exec_weighted;



schedstat_set(curr->statistics.exec_max,

max((u64)delta_exec, curr->statistics.exec_max));



curr->sum_exec_runtime += delta_exec;

schedstat_add(cfs_rq, exec_clock, delta_exec);

<span style="color:#ff0000;"> delta_exec_weighted = calc_delta_fair(delta_exec, curr);</span><span style="color:#ff00;">



</span><span style="color:#ff0000;">curr->vruntime += delta_exec_weighted;</span>

update_min_vruntime(cfs_rq);



#if defined CONFIG_SMP && defined CONFIG_FAIR_GROUP_SCHED

cfs_rq->load_unacc_exec_time += delta_exec;

#endif

}

分析一下:传入的参数curr,delta_exec,执行了calc_delta_fair,从名字入手,这是计算,计算什么?增量,还是公平的,那就是加入了权重,这样计算出了权重值.接着在vruntime上加上权重,这就是进程运行的时间,记账完成.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: