《深入理解Linux内核》--第七章:进程调度:读书笔记

本文深入探讨Linux进程调度机制,涵盖进程状态、调度策略、数据结构和关键函数等内容。介绍了SCHED_FIFO、SCHED_RR及SCHED_NORMAL三种调度类型的工作原理,以及在多处理器系统中的运行队列平衡策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

零、感想
进程调度涉及的 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)
,一个优先级位图, 一个可运行进程集合的
进程数量的计数器。
未命名6
进程描述符
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子集。
未命名6
函数:
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 调度域

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值