JAVA程序员需要知道的计算机底层基础06-进程调度
一个操作系统往往是存在很多进程的,虽然内存是各自独立的,但CPU确是共享,那势必存在一个多个进程之间调度执行的问题,也就是什么时候执行这个进程,什么时候执行另外一个进程的,各自执行多久?这种问题。
linux中的调度方式非常灵活,不是像其他有些操作系统一样固定只有一种的,而是可以根据对应的调度策略进行调度,而调度策略可以由开发内核的进行自定义策略编写,当然linux自身也已经提供了一些调度策略,一般来说我们不需要手动去编写(能编写那你也得会写内核)。
进程调度发展历程
早期的dos系统只支持单任务运行,同一时间内一个操作系统只能干一件事,这个任务死了,整个系统就死了。
调度编写原则
最大限度压榨CPU资源。
进程调度算法
操作系统大多数采用的是抢占式。
linux内核进程调度
在linux2.5的时候,采用的是Unix O(1)调度策略,就是平均的给每个进程分配固定的执行时间片,然后挨个让每个进程执行时间片大小的时间。但这种对交互不友好,例如一个UI进程,输入了一个字符,但这个字符需要等到下一次到这个UI线程的执行时间片的时候才能进行执行,响应效果很差。
在2.6.23之后,采用CFS调度策略:Completely Fair Scheduler 完全公平调度算法。
但可能你会有疑惑,按理说上面那种不就是完全公平了吗,每个进程都有相同的时间片。 但实际上,这也将意味着有些并未在进行处理的进程也会被分配上固定的时间片,而有些紧急需要处理的线程却迟迟得不到处理。
因此CFS算法是按优先级分配时间片的比例,优先级怎么算呢?
例如有a,b进程,分别分配50%的时间片,但当要分配给a的时候,此时发现a并未在执行东西,此时这个时间片将不会分配给a,而是全部给b。
linux会记录每个进程的执行时间, 而当a有东西要执行的时候,,发现a进程虽然被分配了50%的时间片,但在过去时间内并未执行达到所分配的时间片时长,此时将会优先执行a进程,直到执行时间达到50%的时候,a,b进程才重新开始公平竞争。
进程调度基本概念
进程优先级
实时进程优先级大于普通进程,而实时进程之间又划分了0-99的优先级。普通进程之间也存在一个-20到19的优先级,
实时进程与普通进程同时存在的时候,普通进程将完全分配不到时间片,必须等到实时进程执行完。
而大多数进程实际都是普通进程。
linux默认的调度策略
实时进程
SCHED_FIFO:先到先得
SCHED_RR:轮询
对进程的优先级分高低,采取越高优先级别的越先执行,FIFO (First In First Out)。 优先级一样 - RR(Round Robin)轮询执行
普通进程
只有实时进程主动让出CPU或者执行完毕后,普通进程才能执行,然后使用CFS调度算法进行执行。