【发布时间】:2021-05-13 09:57:33
【问题描述】:
我想知道如何在多线程的Linux内核中使用调度机制,我看到sched_yield()系统调用可以将当前线程发送到进程队列的末尾。由于SCHED_OTHER 是默认调度策略,手册不建议在使用SCHED_OTHER 时使用此系统调用,因为它旨在与实时调度策略(man 2 sched_yield)一起使用,并且未与SCHED_OTHER 指定:
sched_yield() 旨在与实时调度策略(即 SCHED_FIFO 或 SCHED_RR)一起使用。未指定将 sched_yield() 与 SCHED_OTHER 等非确定性调度策略一起使用,这很可能意味着您的应用程序设计已损坏。
但是,我从 RedHat 文档中看到 this page 说 sched_yield() 不应该用于实时任务:
sched_yield 系统调用由一个线程使用,允许其他线程有机会运行。通常在使用 sched_yield 时,线程可能会走到运行队列的末尾,需要很长时间才能再次调度,或者可以立即重新调度,从而在 CPU 上创建一个繁忙的循环。调度程序能够更好地确定何时以及是否真的有其他线程想要运行。避免在任何 RT 任务中使用 sched_yield。
那么我应该如何使用sched_yield() 系统调用呢?这对 SCHED_OTHER 或 SCHED_FIFO 政策有什么影响?据我了解,使用SCHED_FIFO策略,除非sched_yield(),否则线程不会被中断,然后第二个请求的线程将被处理,除非它结束,当所有线程排队时第一个线程将继续已被处理(具有 FIFO 行为)。
另外,这个系统调用对SCHED_RR 策略有什么作用,因为所有线程在每个时间段都被部分处理?
【问题讨论】:
-
这只是意味着不要在循环中使用它来替代睡眠。您应该将您的应用重新设计为事件驱动。
-
这将有助于您编辑您的问题并描述您的线程是如何组织的(例如)N-worker 模型或异构线程。通常,每个线程都应该在输入队列上等待 [等待事件]。将工作描述符出列,对其进行操作,形成数据处理流水线_next_stage的描述符,并入队到下一个线程。我已经完成了许多 R/T 嵌入式系统来做这件事。
SCHED_RR具有不同的优先级和保证的延迟/吞吐量,并且从未使用过sched_yield。这样做意味着对整个线程模型的错误设计。
标签: c multithreading linux-kernel posix scheduling