进程的调度
在linux2.6内核中,每一个cpu都有一个运行队列,即内核变量struct runqueue,并且每个cpu都有一个全局变量struct task_struct*,用来保存cpu正在运行的进程是谁
进程的优先级设计
实时进程没有nice值的概念,优先级0~99,普通进程有nice值,通过nice值来影射优先级,nice为-20映射优先级100,nice值为19,映射优先级139
共计140个优先级,0~139
运行队列的设计
活动队列
过期队列
运行队列里有两个指针,分别指向活跃队列和过期队列
进程调度过程
一个进程里保存了运行的时间片,还有所有的寄存器。cpu依靠时钟源的时钟周期(ns)来运行进程的指令,靠时钟源的时钟中断(ms)来更新进程的时间片,假设时钟中断是1ms,时间片10ms,假如cpu处于用户态,时钟中断cpu会陷入内核,执行中断函数将时间片减1ms,然后恢复用户态。假如cpu正在执行系统调用,本来就在内核,那就不会减时间片。等到时间片为0,那这个进程pcb就会保存上下文寄存器,并设置TIF_NEED_RESCHED
标志位
进程调度时机
(1) task_struct
(PCB)
struct task_struct {
// ... 其他字段 ...
struct thread_info *thread_info; // 指向 thread_info
// ... 调度相关字段 ...
};
(2) thread_info
(存储线程状态,包含 TIF_NEED_RESCHED
)
struct thread_info {
unsigned long flags; // 线程状态标志,包括 TIF_NEED_RESCHED
// ... 其他字段 ...
};
进程时间片为0,并不会立即在时钟中断函数里进行进程调度,而是设置标志位,等到cpu寄存器从内核栈里恢复后,去查看pcb中thread_info里flags中有没有设置TIF_NEED_RESCHED标志位,如果有那就进行进程调度
,cpu寄存器从内核栈里恢复,并且准备切换成内核态的这个时间节点,我们称为安全点