Linux相关面试题 进程调度的问题

之前面试腾讯的时候,被问过这个问题,回答的不是太准确。整理了如下内容,如果有不正确的地方,还请指出来。

Linux 内核实现了如下四种调度类,按优先级从高到低排列:

  1. 停止类(主要用于多个CPU之间的负载均衡和CPU的热拔插)
  2. 实时类
  3. 完全公平调度类
  4. 空闲类(负责将CPU置于停机状态,直到中断将其唤醒,只有在没有其它任务的时候才能被执行)

和应用层关系密切的两种调度类是实时类和完全公平调度类(CFS),另两种知道其存在就行,一般的后台开发只能接触到这两类。

Linux对实时进程提供了两种调度策略:

  1. 先进先出(SCHED_FIFO)

FIFO策略是一种简单的策略,即先进先出,它没有时间片的概念,只要没有更高优先级的进程就绪,使用该调度策略的进程就会一直进行。直到发生如下情况:

  • 自动放弃CPU,如执行阻塞调用。
  • 进程退出。
  • 被更高优先级进程抢占。

    2.        时间片轮转(SCHED_RR)

在时间片轮转的策略中,具有相同优先级的进程轮流进行,进程每次使用CPU的时间为一个固定长度的时间片。使用该策略的进程一旦被调度器选中,就会一直占用CPU资源,直到发生下面某种情况:

  • 时间片耗尽
  • 进程自动放弃CPU,如执行阻塞调用。
  • 进程退出。
  • 被更高优先级进程抢占。

完全公平调度类的调度策略包括(SCHED_OTHER或者SCHED_NORMAL),我们平常开发过程中,使用到的进程就是这种分时进程,CFS底层实现是基于红黑树的,实时进程是基于优先级队列实现。

普通的CFS分时进程,可以通过如下两个系统调用变为实时进程。

sched_getscheduler()和sched_setscheduler(),这两个函数主要调整进程 的优先级以及调度策略。

关于优先级,Linux中为实时进程提供了99个优先级,从内核层面来看,从0到99范围内的优先级属于实时进程的调度范围。从100~139共40个等级属于CFS调度。

此外关于CPU的亲和力。

在对称多处理器(SMP)环境中,一个进程被重新调度时,不一定是在上次执行的CPU上运行。

同一个进程在不同 的CPU之间迁移会带来性能的损失,损失的主要原因在于缓存。在进程迁移到新的处理器上后写入新数据到内存时,原有处理器的缓存就过期了。当进程在不同处理器之间迁移时,会带来两方面的性能损失:

  • 进程不能访问老的缓存数据
  • 原处理器中缓存中的数据必须标记为无效。

由于迁移会带来性能损失,因此进程调度趋于把进程固定在一个处理器上执行。

有时候需要把进程绑定到某个或某几个CPU上运行,这就需要设置进程的CPU硬亲和力了。Linux提供了非标准的系统调用来获取和修改进程的硬亲和力:即sched_setaffinity()函数和sched_getaffinity()

 

参考资料:

1. 《Linux环境编程 从应用到内核》高峰。

2. 《深入理解Linux内核》

=============================================================================================

Linux应用程序、内核、驱动、后台开发交流讨论群(745510310),感兴趣的同学可以加群讨论、交流、资料查找等,前进的道路上,你不是一个人奥^_^。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章