进程管理和调度
1 进程优先级
进程类型
-
硬实时进程,Linux主流不支持
-
软实时进程
-
普通进程,可分配优先级
抢占式多任务处理;CFS,调度实体,
2 进程生命周期
进程状态
-
运行
-
等待
-
睡眠
进程表,僵尸进程(资源已释放,但进程表项还存在);
抢占式多任务处理:
-
普通进程总是可能被抢占
-
内核态系统调用无法被其他进程抢占,但中断可以中止系统调用
-
中断可以暂停用户态和内核态进程,具有最高优先级
内核2.5后内核抢占支持内核系统调用被其他进程抢占;
3 进程表示
struct task_struct结构
-
状态和执行信息
-
虚拟内存信息
-
进程身份凭据
-
文件和文件系统信息
-
进程特定于CPU的运行数据线程信息
-
进程间通信有关信息
-
信号处理程序
state进程当前状态
-
TASK_RUNNING
-
TASK_INTERRUPTIBLE
-
TASK_UNINTERRUPTIBLE
-
TASK_STOPPED
-
TASK_TRACED
-
EXIT_ZOMBIE, EXIT_DEAD
资源限制rlimit
3.1 进程类型
-
fork
-
exec
-
clone,用于实现线程
3.2 命名空间
-
概念:虚拟化,容器,建立系统不同的视图,chroot机制,
-
fork或clone时可选择命名空间选项
-
unshare系统调用
-
-
实现:uts、ipc、mnt、pid、user、net等命名空间,struct nsproxy;
-
进程ID号:全局ID、局部ID;pid,upid,pid_namespace等之间的关系:
-
upid: (number, pid_namespace)
-
pid_namespace: number->pid
-
pid: (level, upid, …) pid->task_struct->pid
-
会为pid的每个命名空间分配一个局部PID,使用idr(radix_tree)数据结构;
-
-
进程关系:使用链表和指针表示;
4 进程管理相关系统调用
4.1 进程复制
-
fork,COW写时复制
-
vfork,父子进程共享数据
-
clone,产生线程,对父子进程之间的共享、复制进行精确控制
kernel_clone->copy_process
4.2 内核线程
4.3 启动新程序
execve系统调用,二进制格式,
4.4 退出进程
exit系统调用,
5 调度器的实现
5.1 概观
CFS;进程等待时间红黑树排序;虚拟时钟;进程优先级Nice值;
-
进程有不同优先级需要考虑
-
进程不能切换太频繁,多媒体系统延迟;
5.2 数据结构
-
调度类(实现调度策略,策略模式)
-
任务切换(CPU相关)
task_struct的相关成员
sched_class调度器类(提供一堆回调函数)
就绪队列,各个活动进程只出现在一个就绪队列中:
- struct rq,嵌入各种子就绪队列(cfs_rq,rt_rq,dl_rq)
- 每个CPU包含一个就绪队列,per-cpu数据
调度实体,sched_entity类,进程是可调度实体,但可调度实体更为广义;
5.3 处理优先级
-
优先级的内核表示:实时优先级、普通优先级(Nice值)
-
计算优先级:综合考虑动态优先级、普通优先级、静态优先级;
-
计算负荷权重:struct load_weight,优先级权重值转换表,转换考虑实时进程(是普通进程的两倍);就绪队列也关联一个负荷权重;
5.4 核心调度器
-
周期性调度器scheduler_tick,按照一定周期调用该函数;
-
主调度器schedule:主动让出CPU给另一个进程,内核系统调用返回后检查重调度标志TIF_NEED_RESCHED;。。。
-
与fork的交互;
-
上下文切换;context_switch,switch_mm,switch_to,惰性TLB,switch_to三个参数传递两个变量prev = switch_to(prev, next), A->B->C->A, prev = C;惰性FPU模式;
6 完全公平调度类
struct fair_sched_class
6.1 数据结构
6.2 CFS操作
6.3 队列操作
6.4 选择下一个进程
6.5 处理周期性调度器
6.6 唤醒抢占
6.7 处理新进程
7 实时调度类
7.1 性质
7.2 数据结构
7.3 调度器操作
8 调度器增强
8.1 SMP调度
8.2 调度域和控制组
8.3 内核抢占和低延迟相关工作