首页 > 解决方案 > sched_yield() 系统调用和实时调度策略

问题描述

我想知道如何在多线程的Linux内核中使用调度机制,我看到sched_yield()系统调用可以将当前线程发送到进程队列的末尾。由于SCHED_OTHER是默认调度程序策略,因此手册不建议在使用时使用此系统调用,SCHED_OTHER因为它旨在与实时调度策略(man 2 sched_yield)一起使用并且未指定SCHED_OTHER

sched_yield() 旨在与实时调度策略(即SCHED_FIFO 或SCHED_RR)一起使用。未指定将 sched_yield() 与 SCHED_OTHER 等非确定性调度策略一起使用,这很可能意味着您的应用程序设计已损坏。

但是,我从 RedHat 文档中看到这个页面说不sched_yield()应该与实时任务一起使用:

sched_yield 系统调用由允许其他线程有机会运行的线程使用。通常在使用 sched_yield 时,线程可能会走到运行队列的末尾,需要很长时间才能再次调度,或者可以立即重新调度,从而在 CPU 上创建一个繁忙的循环。调度程序能够更好地确定何时以及是否真的有其他线程想要运行。避免在任何 RT 任务上使用 sched_yield。

那么我应该如何使用sched_yield()系统调用呢?这对 aSCHED_OTHERSCHED_FIFOpolicy 有什么影响?据我了解,使用SCHED_FIFO策略,除非 a ,否则线程不会被中断sched_yield(),然后第二个请求的线程将被处理,除非它结束,当所有线程队列都处理完毕后,第一个线程将继续(使用 a先进先出行为)。

另外,这个系统调用会对SCHED_RR策略做什么,因为所有线程都在每个量程中被部分处理?

标签: cmultithreadinglinux-kernelposixscheduling

解决方案


Linus Torvalds 关于以下内容的评论sched_yield

问题是“产量”几乎没有定义。它的定义实际上是关于具有优先级的实时调度程序的实时行为的单个队列。

但那个“定义”几乎与实际使用无关。有各种各样的随机人使用它,有些人可能将其用于锁定,而有些人将其用于其他用途。

...

sched_yield()基本上是历史垃圾。即使对于定义的用法,它也经常是错误的,因为很久以前,“我们一次只运行一件事”的时间已经过去了。如果您的 RT 系统实际上有多个并发线程(而不是仅限于专用 CPU),那么即使在那里也不是那么明确。但至少在那里你仍然可以假装它是。


推荐阅读