Linux进程调度机制(1)

  进程调度负责决定哪个进程投入运行,何时运行以及运行多长时间。

  进程调度:非抢占式和抢占式
  Linux这么酷的系统当然是抢占式的喽。

  进程在被抢占之前可以运行的时间是预先设定好的,叫做时间片。有效管理时间片能使调度程序从系统全局角度作出调度决定,避免个别进程独占系统资源。

I/O消耗型/处理器消耗型
  I/O消耗型:进程的大部分时间用来提交I/O请求或是等待I/O请求,这样的进程经常处于可运行状态,但通常只运行很短时间,在等待I/O时会阻塞。
  处理器消耗型:进程大部分时间都在执行代码,除非被抢占,否则一直执行,没太多I/O需求。调度器不应该经常让他们执行,应尽量降低它们的调度频率,而延长其运行时间。

  调度策略就是要在这两个矛盾中寻找平衡:进程响应迅速(响应时间短)和最大系统利用率(高吞吐量),linux倾向于优先调度IO消耗性。

  时间片:进程在被抢占前所能持续运行的时间。
  时间片过长会导致系统对交互响应表现欠佳,时间片太短会明显增加进程切换耗时。
  IO消耗型不需要长的时间片,而处理器消耗型的进程希望越长越好(提高高速缓存命中率)。

  Linux的CFS调度器没有直接分配时间片到进程,而是分配处理器的使用比。这样进程所获得的处理器时间其实是和系统负载密切相关的,这个比例进一步还会受进程nice值(优先级)影响。具有更小nice值的进程会被赋予高权重,从而有用更多的处理器使用比。

  我们先来看在什么情况下要执行调度程序。
  Linux调度时机主要有:
  1)Process/thread creation Process/thread exit
  2)Blocking on I/O or synchronization
  3) I/O interrupt
  4) Clock interrupt (pre-emptive scheduling)
  1、进程状态转换的时刻:进程终止、进程睡眠;
  2、当前进程的时间片用完时(current->counter=0);
  3、设备驱动程序
  4、进程从中断、异常及系统调用返回到用户态时;
  时机1,进程要调用sleep()或exit()等函数进行状态转换,这些函数会主动调用调度程序进行进程调度;
  时机2,由于进程的时间片是由时钟中断来更新的,因此,这种情况和时机4是一样的。
  时机3,当设备驱动程序执行长而重复的任务时,直接调用调度程序。在每次反复循环中,驱动程序都检查need_resched的值,如果必要,则调用调度程序schedule()主动放弃CPU。
  时机4,如前所述,不管是从中断、异常还是系统调用返回,最终都调用ret_from_sys_call(),由这个函数进行调度标志的检测,如果必要,则调用调用调度程序。那么,为什么从系统调用返回时要调用调度程序呢?这当然是从效率考虑。从系统调用返回意味着要离开内核态而返回到用户态,而状态的转换要花费一定的时间,因此,在返回到用户态前,系统把在内核态该处理的事全部做完。

Linux的调度算法:CFS(完全公平调度)
  CFS 背后的主要想法是维护为任务提供处理器时间方面的平衡(公平性)。当分给某个任务的时间失去平衡时(意味着一个或多个任务相对于其他任务而言未被给予相当数量的时间),应给失去平衡的任务分配时间,让其执行。
  CFS在所有可运行总数基础上计算出一个进程应该运行多久的时间。允许每个进程运行一段时间,循环轮转,选择运行最少的进程作为下一个运行进程。每个进程都按其权重在全部可运行进程中所占比例的“时间片”来运行。
  当运行进程数量很大时,为避免频繁的切换消耗,CFS设置了底线。每个进程时间片的最小粒度是1ms,也就是说就算进程数量无限大,每个最少也能获得1ms的运行时间。

  与之前的 Linux 调度器不同,它没有将任务维护在运行队列中,CFS 维护了一个以时间为顺序的红黑树。 我们知道红黑树是是自平衡的,树上的操作 时间复杂度为O(log n),可以快速高效地插入或删除任务。

   

  Linux 内的所有任务都由称为 task_struct 的任务结构表示,task_struct 中会创建一个名为 sched_entity 的新结构来跟踪调度信息。

   

  task_struct 描述进程任务并包含 sched_entity 结构。该结构包含 rb_node 引用、负载权重以及各种统计数据。最重要的是, sched_entity 包含 vruntime(64 位字段),它表示任务运行的时间量,并作为红黑树的索引。
  rb_node 包含在 sched_entity 结构中,用于表示红黑树的每个节点,它只包含子引用和父对象的颜色。
  此外,红黑树的根通过 rb_root 元素通过 cfs_rq 结构引用。红黑树的叶子不包含信息,但是内部节点代表一个或多个可运行的任务。
  对处理器需求最多的任务 (最低虚拟运行时)存储在树的左侧,处理器需求最少的任务(最高虚拟运行时)存储在树的右侧。 为了公平,调度器然后选取红黑树最左端的节点调度为下一个以便保持公平性。任务通过将其运行时间添加到虚拟运行时, 说明其占用 CPU 的时间,然后如果可运行,再插回到树中。这样,树左侧的任务就被给予时间运行了,树的内容从右侧迁移到左侧以保持公平。 因此,每个可运行的任务都会追赶其他任务以维持整个可运行任务集合的执行平衡。

   

  
  红黑树的键值一般由进程已经占用的CPU时间和进程的优先级决定。
  其中进程已经占用的CPU时间对键值的影响最大,我们可以简单地认为键值就等于进程已占用的 CPU时间。因此该值越大,键值越大,从而使得当前进程向红黑树的右侧移动。

  就 CFS 部分而言,调度函数非常简单。 在 ./kernel/sched.c 中,您会看到通用 schedule() 函数,它会先抢占当前运行任务(除非它通过 yield() 代码先抢占自己)。注意 CFS 没有真正的时间切片概念用于抢占,因为抢占时间是可变的。 当前运行任务(现在被抢占的任务)通过对 put_prev_task 调用(通过调度类)返回到红黑树。 当 schedule 函数开始确定下一个要调度的任务时,它会调用 pick_next_task 函数。此函数也是通用的(在 ./kernel/sched.c 中),但它会通过调度器类调用 CFS 调度器。 CFS 中的 pick_next_task 函数可以在 ./kernel/sched_fair.c(称为 pick_next_task_fair())中找到。 此函数只是从红黑树中获取最左端的任务并返回相关 sched_entity。通过此引用,一个简单的 task_of() 调用确定返回的 task_struct 引用。通用调度器最后为此任务提供处理器。这部分会在后面文章详细剖析。

下面是找到的一段英文总结,个人感觉不错:
• Scheduling decision:
  – Pick the leftmost task (smallest virtual runtime)
• When a task is moved from running → ready:
  – Add execution time to the per-task run time count
  – Insert the task back in the sorted tree
• Heuristic: decay factors
  – Determine how long a task can execute
  – Higher priority tasks have lower factors of decay.
  – Avoids having run queues per priority level

  The Linux CFS scheduler provides an efficient algorithm for selecting which task to run next. Each runnable task is placed in a red-black tree—a balanced binary search tree whose key is based on the value of vruntime.
  When a task becomes runnable, it is added to the tree. If a task on the tree is not runnable ( for example, if it is blocked while waiting for I/O ), it is removed. Generally speaking, tasks that have been given less processing time ( smaller values of vruntime ) are toward the left side of the tree, and tasks that have been given more processing time are on the right side. According to the properties of a binary search tree, the leftmost node has the smallest key value, which for the sake of the CFS scheduler means that it is the task with the highest priority . Because the red-black tree is balanced, navigating it to discover the leftmost node will require O(lgN) operations (where N is the number of nodes in the tree). However, for efficiency reasons, the Linux scheduler caches this value in the variable rb_leftmost, and thus determining which task to run next requires only retrieving the cached value.

参考:
http://www.ibm.com/developerworks/cn/linux/l-completely-fair-scheduler/

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Linux 进程调度是指系统内核在多个进程之间调度 CPU 时间片的过程。它根据各种调度算法和优先级来决定每个进程获得 CPU 时间的顺序。常见的 Linux 调度算法有 Completely Fair Scheduler(CFS)和 Round Robin。 CFSLinux 默认的调度算法,它根据每个进程的运行时间和优先级来决定调度顺序。 ### 回答2: Linux进程调度是操作系统对于进程的管理和分配资源的算法。在Linux系统中,进程是运行程序的实体,而进程调度则是决定进程运行顺序和时间的机制Linux采用了基于优先级的进程调度算法,通过动态地调整进程的优先级来决定进程被选中的概率。Linux内核中定义了两种进程调度策略:一种是实时调度策略,包括FIFO(先进先出)和RR(时间片轮转);另一种是非实时调度策略,包括CFS(完全公平调度)。 在实时调度策略中,FIFO按照进程进入系统的先后顺序进行调度时间片进程自行声明。而RR则将时间分成固定大小的时间片,每个进程只能运行一个时间片,然后切换到下一个进程。这两种调度策略主要适用于对实时性要求较高的应用。 而在非实时调度策略中,CFS采用了完全公平调度算法。CFS通过计算进程的虚拟运行时间,并将其与其他进程进行比较,从而确定下一个被调度进程CFS倾向于将CPU时间平均地分配给每个进程,并避免某个进程独占CPU资源。 另外,Linux还引入了时间片的概念。时间片是CPU分配给每个进程最小时间单位,它的大小直接影响着进程调度顺序。时间片越小,进程切换的频率就越高,系统的响应速度也会更快。 总的来说,Linux进程调度根据进程的优先级、类型和运行状态等因素,动态地为每个进程分配CPU资源,从而实现多任务的并发执行,提高系统的整体性能和响应速度。 ### 回答3: Linux进程调度是操作系统中重要的组成部分,它负责决定在多个进程同时运行时,每个进程被分配CPU的时间片长短和优先级。Linux通过采用时间片轮转和优先级调度的方式来管理进程时间片轮转调度算法是一种公平的调度方法,它将CPU的运行时间划分成较小的时间片,并按照轮转的方式分配给每个进程。当一个进程时间片用完后,它会被放到就绪队列的末尾,等待下一次调度。这种调度方式保证了每个进程能够公平地使用CPU资源,避免了某些进程长时间占用CPU的情况。 Linux还采用了优先级调度算法,每个进程都有一个优先级值,数值越高表示优先级越高。在就绪队列中,调度器会将优先级最高的进程分配给CPU执行。如果两个进程的优先级相同,那么按照时间片轮转的方式进行调度。通过设定不同的进程优先级,可以实现进程的优先级控制和资源分配。 此外,Linux还引入了实时调度策略,包括实时先进先出和实时循环调度。实时调度算法是为了满足对实时任务有严格响应时间要求的场景,保证实时任务能够及时地被执行。 总结来说,Linux进程调度通过时间片轮转和优先级调度的方式,保证了进程的公平性和高优先级任务的及时响应能力。同时,引入实时调度策略,满足对实时任务的特殊需求。这些调度算法的运作机制和相互配合,为Linux操作系统的稳定性和高效性提供了重要的保障。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

One2zeror

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值