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

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被赋值为nowexec_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上加上权重,这就是进程运行的时间,记账完成.

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值