《Linux内核设计与实现》学习【2】—— 进程调度

本文深入探讨了Linux调度器的工作原理,包括CFS(完全公平调度)如何分配处理器时间,以及进程的优先级设定。CFS通过红黑树管理进程,确保每个进程获得公平的执行时间。此外,文章还介绍了抢占机制,包括用户级和内核级抢占的情况,以及何时会发生进程切换。
摘要由CSDN通过智能技术生成

1 简介

(1)调度程序工作
  1)将哪个投入运行
  2)何时运行及运行多长时间
(2)I/O消耗型和处理器消耗型
  I/O消耗型:大部分时间处理IO请求
  处理器消耗型:大部分时间在执行代码
(3)优先级
两种:
  1)nice值:范围是-20~+19,值越大优先级越低
  2)实时优先级:范围是0~99,值越大优先级越高。
任何实时进程的优先级大于普通进程
(4)完全公平调度(Completely Fair Scheduler,CFS)
  理念:每个进程获得1/n的处理能力
  做法:每个进程运行一段时间、循环轮转、选择运行最少的进程作为下一个进程

2 调度器类

  目的是将调度器模块化,目前有deadline调度器 、实时调度器、完全公平调度器 、idle task。
  调度器主要入口schedule(),调用pick_next_task(),按优先级从高到低,检查每个调取器中的进程。

static inline struct task_struct *
pick_next_task(struct rq *rq)
{
	const struct sched_class *class;
	struct task_struct *p;

	if (likely(rq->nr_running == rq->cfs.nr_running)) {//CFS
		p = fair_sched_class.pick_next_task(rq);
		if (likely(p))
			return p;
	}

	class = sched_class_highest;
	for ( ; ; ) {
		p = class->pick_next_task(rq);
		if (p)
			return p;
		class = class->next;
	}
}

3 CFS调度实现

3.1 时间

  通过update_curr()实现了时间记账功能,更新vruntime。
注:
  (1)分配给进程的时间 = 总的cpu时间 * 进程的权重/就绪队列(runqueue)所有进程权重之和
  (2)nice值为0的进程的虚拟时间和实际时间是相等的

3.2 进程选择

(1)选择任务
  选择具有最小的vruntime运行。CFS使用红黑树组织进程队列,并将最小的vruntime缓存在rb_leftmost字段中。__pick_next_entity选择最左边的进程

static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq)
{
	struct rb_node *left = cfs_rq->rb_leftmost;

	if (!left)
		return NULL;

	return rb_entry(left, struct sched_entity, run_node);
}

(2)加入与删除进程
  加入——enqueue_entity(),更新统计信息,并调用__enqueue_entity(),将进程插入到红黑树中。
  删除——dequeue_entity(),从红黑树中删除进程

3.3 抢占

(1)用户抢占发生情况
  1)从系统调用返回用户空间
  2)从中断(异常)处理程序返回用户空间。
(2)内核抢占发生情况
  条件:没有持有锁,内核就可以抢占,preemt_count记录使用锁情况。
  中断返回时,若need_resched被设置,若preemt_count为0,抢占;若不为0,直接返回。
发生情况:
  1)中断处理程序正在执行,且返回内核空间之前
  2)内核代码再一次具有可抢占的时候
  3)内核任务中显示地调用schedule()
  4)内核中的任务阻塞

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值