进程会一直执行直到本身主动中止运行(这一步骤称为让步)linux
Linux/Unix使用的是抢占式的方式;强制的挂起进程的动做就叫作抢占。进程在被抢占以前可以运行的时间是预先设置好的(也就是进程的时间片)算法
(1)进程分为I/O消耗型和处理器消耗型函数
I/O消耗型:进程的大部分时间用来提交I/O请求或是等待I/O请求。这样的进程常常处于可运行状态,但一般是短短一下子。由于它在等待更多的I/O请求时最后总会阻塞。ui
处理器消耗型:把时间大多用在执行代码上。除非被抢占,不然一直不停地运行。对于这类,调度策略尽可能下降他们的调度频率,而延长其运行时间。spa
(2)调度策略一般在两个矛盾的目标中间寻找平衡:进程响应迅速(响应时间短)和最大系统利用率(高吞吐量)。unix
(3)Unix系统更倾向于I/O消耗型程序,以提供更好的程序响应速度。队列
在某些系统中,优先级高的进程使用的时间片也比较长。调度程序老是选择时间片未用尽并且优先级最高的进程运行。用户和系统均可以经过设置进程的优先级来影响系统的调度。进程
Linux采用了两种不一样的优先级范围——nice值和实时优先级值。事件
(1) nice值,范围是-20到19,数值越大优先级越低,默认值为0。Linux中,nice值则表明时间片的比例。能够经过ps-el命令查看系统中的进程列表,结果中标记NI的一列就是进程对应的nice值。内存
(2) 实时优先级值,默认0到99,数值越大优先级越高。任何实时进程的优先级都高于普通的进程。
查看进程列表以及对应的实时优先级:ps-eo state,uid,pid,ppid,rtprio,time,comm.
代表进程被抢占前所能持续运行的时间。长时间片致使系统交互表现欠佳。
(1)Linux的CFS调度器:没有直接分配时间片到进程,而是将处理器的使用比划分给进程。其抢占时机取决于新的可运行程序消耗了多少处理器使用比。若是消耗的使用比比当前进程小,马上投入运行,抢占当前进程;不然推迟运行。
(1)Linux调度器是以模块方式提供的(也就是调度器类),目的是容许不一样类型的进程能够有针对性地选择调度算法
(2)调度器类容许多种不一样的可动态添加的调度算法并存,调度属于本身范畴的进程;
(3)调度器代码会按照优先级顺序遍历调度类,拥有一个可执行进程的最高优先级的调度器类胜出,去选择下面要执行的那一个程序;
(1)将nice值映射到时间片的话,就必须将nice值对应处处理器的绝对时间;这样会致使进程切换没法最优进行;
(2)若是使用相对nice值,所带来的效果将会极大取决于其nice的初始值;
(3)若是执行nice值到时间片的映射,时间片极大受制于定时器。
目标延迟:CFS为完美多任务中的无限小调度周期的近似值设立的一个目标。越小的调度周期将带来越好的交互性,同时也更接近完美的多任务。但必须承受更高的切换代价和更差的系统总吞吐能力。
最小粒度:CFS引人每一个进程得到的时间片底线,这个底线称为最小粒度。
CFS中,任何进程所得到的处理器时间是由它本身和其余全部可运行进程nice值的相对差值决定。任何nice值对应的绝对时间是处理器的使用比。
(1)CFS算法核心:选择具备最小vrntime的任务
(2)具体作法:利用红黑树rbtree(以节点形式存储数据的二叉树)
(1)进程调度的主要入口点是函数schedule(),定义在kernel/sched.c中;这正是内和其余部分用于调度进程调度器的入口
(2)这一函数最重要的工做就是调用pick_next_state(),依次检查每个调度类,并从最高优先级的调度类中,选择最高优先级进程
(1)进程休眠必定是为了等待一些事件
(2)唤醒操做由函数wake_up()进行
上下文切换由定义在kernel/sched.c中的context_switch()函数负责,每当一个新的进程被选出来准备运行的时候,schedule()就会调用该函数:
发生时机:
从中断处理程序返回用户空间时。
(1)只要没有锁,内核就能够进程抢占;
(2)为了支持抢占,每一个进程的thread_info都加入了preempt_count计数器(初值为0,每当使用锁的时候就加1,释放锁的时候数值减1),当数值为0时,内核就能够抢占
(3)内核抢占发生在:
linux 提供两种实时调度策略SCHED_FIFO和SCHED_RR。