目录
进程分类
实时进程
和用户交互的进程,需要及时响应
普通进程
影响不需要那么及时的进程,压缩文件、视频的编解码
上下文切换
cpu进程切换的时间在1500ns~2000ns之间
多个进程 分割时间片
p1 context,执行环境(上下文),保存在内核:程序计数器,变量,寄存器的值,运行到第几行
调度算法
FIFO(first in first out)
linux管道
优势:简单
劣势:无法及时响应
STF(short time first)
谁的进程时间段,谁先调度
优势:等待时间最短
劣势:长时进程先来,还是得等;长时进程可能长时无法响应
STCF
谁先完成,谁先被调度
划时代的,抢占式的。
后面的来的进程可以抢占前面的进程时间的。cpu先调度完成时间短的,在切换回去调度完成时间长的。
劣势:长时进程响应时间太长了
RR
轮询的方式
1s分为很多时间片,把这些时间分给每一个进程
https://github.com/zorrozou/zorrozou.github.io/blob/master/docs/books/linuxde-jin-cheng-you-xian-ji.md
进程队列
全局队列
多个CPU 全局队列
加锁,释放锁的各种操作,会让性能很低。
局部队列
多个cpu每个cpu有自己的进程队列
每个cpu自己的队列里面取,然后执行
进程优先级
不是每一个进程都有相同的优先级
查看进程的优先级 ps-l
S 进程状态(man ps 看具体) PID 自己的ID PPID 父进程ID PRI 优先级 NI nice
nice是什么?
用户可以设置的值,这个值可以影响优先级,静态优先级,可以更改(renice)
linux nice 进程的nice值,他对别的进程的好的程度;一个进程nice值的程度越高,他越不会抢占cpu;nice越高,优先级越低。
怎么设置一个nice值?
nice -n xx proc
renice
优先级和nice的范围
值越大,优先级越低
nice -20~19
优先级 0~130
源码:
Sched.c
/*
* Convert user-nice values [ -20 ... 0 ... 19 ]
* to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
* and back.
*/
#define NICE_TO_PRIO(nice) (MAX_RT_PRIO + (nice) + 20)
#define PRIO_TO_NICE(prio) ((prio) - MAX_RT_PRIO - 20)
#define TASK_NICE(p) PRIO_TO_NICE((p)->static_prio)
/*
* 'User priority' is the nice value converted to something we
* can work with better when scaling various scheduler parameters,
* it's a [ 0 ... 39 ] range.
*/
#define USER_PRIO(p) ((p)-MAX_RT_PRIO)
#define TASK_USER_PRIO(p) USER_PRIO((p)->static_prio)
#define MAX_USER_PRIO (USER_PRIO(MAX_PRIO))
Sched.h
/*
* Priority of a process goes from 0..MAX_PRIO-1, valid RT
* priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
* tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority
* values are inverted: lower p->prio value means higher priority.
*
* The MAX_USER_RT_PRIO value allows the actual maximum
* RT priority to be separate from the value exported to
* user-space. This allows kernel threads to set their
* priority to a value higher than any user task. Note:
* MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.
*/
#define MAX_USER_RT_PRIO 100
#define MAX_RT_PRIO MAX_USER_RT_PRIO
#define MAX_PRIO (MAX_RT_PRIO + 40)
#define DEFAULT_PRIO (MAX_RT_PRIO + 20)
实时进程 用户的交互 需要即使响应所以和普通进程的优先级是要分开的、
实时进程的优先级是从0~100 #define MAX_USER_RT_PRIO 100
普通进程来说:100~139
静态优先级是什么?
nice值来决定的优先级,权力在用户,用户在一开始就设定优先级,同时可以更改
动态优先级是什么?
内核来决定的,有些进程会超时,要收到惩罚,内核就会自动取修改优先级,有些进程收到不公平的待遇,内核就会调高他的优先级。
linux调度器
O(n)调度器
cpu 进程队列 队列里面放的是带有优先级的进程
链表 数据
遍历这个队列 找到优先级最高的这个进程。
效率非常低
O(1)调度器
位运算是最快的。0-139的一个范围。
优先级映射成了一个bitmap。这里也解释了为什么优先级的值越低优先级越高,因为bitmap是从最低位开始找。(大数据常用)
在这个优先级上有进程,那么这个位就置位1.
active expire 两个队列会交换,指针的交换十分快。
当time_slice为0时,表示当前进程的时间片用完,调度器判断当前进程的类型,如果是交互式进程或者实时进程,则重置其时间片并重新插入active数组。如果不是交互式进程则从active数组中移到expired数组,并根据上述公式重新计算时间片。这样实时进程和交互式进程就总能优先获得CPU。然而这些进程不能始终留在active数组中,否则进入expire数组的进程就会产生饥饿现象。当进程已经占用CPU时间超过一个固定值后,即使它是实时进程或者交互式进程也会被移到expire数组中。当active数组中的所有进程都被移到expire数组中后,调度器交换active数组和expire数组。因此新的active数组又恢复了初始情况,而expire数组为空,从而开始新的一轮调度。
CFS调度器
完全公平调度器
分时间片,每个进程相对公平
保证每个进程都能分到时间片
virtual time
优先级高的进程 10ms(实际) 1ms(记录)
优先级低的进程 10ms(实际)10ms(记录)
红黑树 cpu调度的时候总是取最左边的这个进程进行调度。