欢迎光临散文网 会员登陆 & 注册

Linux--进程调度

2023-03-18 15:36 作者:圣母和正负喜欢没办法  | 我要投稿

1 结构

2  优先级

0--99 :实时优先级

100--139 : 普通优先级

普通优先级nice值:-20--+19

优先级调整:

p->prio = effective_prio(p);

static int effective_prio(struct task_struct *p)

{

p->normal_prio = normal_prio(p);

/*如果实时优先级或者提高到实时优先级,则保持优先级不变,否则返回普通优先级*/

if (!rt_prio(p->prio))

return p->normal_prio;

return p->prio;

}

动态优先级:task_struct->prio

普通优先级:task_struct->normal_prio

静态优先级:task_struct->static_prio     //static_prio计算起点

nice权重:/*   0 */      1024,       820,       655,       526,       423,

1>A B两个进程,nice都为0 则每个进程的份额1024/(1024+1024)=50%,则即每个进程得到cpu的时间各50%.

2>A ,B两个进程,A的nice=0,B的nice=1;
则A 1024/(1024+820)=0.55%,B 820/(1024+820)=0.45%,这样产生10%的差额


调度图

调度类:

extern const struct sched_class stop_sched_class;

extern const struct sched_class dl_sched_class;

extern const struct sched_class rt_sched_class;//实时调度

extern const struct sched_class fair_sched_class;//完全公平调度

extern const struct sched_class idle_sched_class;

调度相关成员:

struct task_struct { 

int prio;//动态优先级

//静态优先级,进程启动时分配的优先级,,可以用Nice和sched_setscheduler系统调用修改,否则一直保持恒定

int static_prio;

int normal_prio;//动态优先级

//实时优先级 0-99  值越大优先级越高

unsigned int rt_priority;

//调度类

const struct sched_class *sched_class;

//调度实体

struct sched_entity se;

//实时调度实体

struct sched_rt_entity rt;

//idle 调度实体

struct sched_dl_entity dl;

unsigned int policy;//调度策略 SCHED_NORMAL  SCHED_BATCH SCHED_IDLE SCHED_RR SCHED_FIFO

int nr_cpus_allowed;//限制进程可以再哪个处理器上运行

struct sched_info sched_info;//调度信息

...

}

调度类:

struct sched_class {

const struct sched_class *next;//链表指针,当系统中有多个调度类,安装优先级排除排成一个链表

//进程加入到执行队列中,即将调度实体放入红黑树中

void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);

void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);

//放弃CPU执行权,实际上该函数执行先出对后入队,它直接将调度实体放在红黑树的最右端

void (*yield_task)   (struct rq *rq);

bool (*yield_to_task)(struct rq *rq, struct task_struct *p, bool preempt);

//用于检查当前进程是否可被新进程抢占

void (*check_preempt_curr)(struct rq *rq, struct task_struct *p, int flags);

struct task_struct *(*pick_next_task)(struct rq *rq);

//选择下一个要运行的进程

void (*put_prev_task)(struct rq *rq, struct task_struct *p);

//将进程回放到运行队列中

void (*set_next_task)(struct rq *rq, struct task_struct *p, bool first);

...

就绪类:

struct rq {

raw_spinlock_t lock;

unsigned int nr_running;//队列上可以运行的进程数目

unsigned long nr_load_updates;

u64 nr_switches;

struct cfs_rq cfs;//cfs调度

struct rt_rq rt;//实时调度

struct dl_rq dl;//空闲调度

unsigned long nr_uninterruptible;

struct task_struct __rcu *curr;

struct task_struct *idle;

struct task_struct *stop;

unsigned long next_balance;

struct mm_struct *prev_mm;

调用实体:

//task_struct中内嵌sched_entity 所以进程是可调度实体

struct sched_entity {

struct load_weight load;//制定了权重,决定了各个实体占队列总负荷的比例

unsigned long runnable_weight;

struct rb_node run_node;//红黑树节点,使得实体可以在红黑树上排序

struct list_head group_node;

unsigned int on_rq;//该实体是否 在就绪队列上接收调度

u64 exec_start;//更新到当前时间

u64 sum_exec_runtime;//差值

u64 vruntime;//虚拟时钟上流逝的时间

u64 prev_sum_exec_runtime;//进程被撤销CPU时,将sum_exec_runtime保存到prev_sum_exec_runtime,而sum_exec_runtime持续增长

...

}


Linux--进程调度的评论 (共 条)

分享到微博请遵守国家法律