【问题标题】:sched_yield() system call and real time scheduling policiessched_yield() 系统调用和实时调度策略
【发布时间】: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 pagesched_yield() 不应该用于实时任务:

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

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

另外,这个系统调用对SCHED_RR 策略有什么作用,因为所有线程在每个时间段都被部分处理?

【问题讨论】:

  • 这只是意味着不要在循环中使用它来替代睡眠。您应该将您的应用重新设计为事件驱动。
  • 这将有助于您编辑您的问题并描述您的线程是如何组织的(例如)N-worker 模型或异构线程。通常,每个线程都应该在输入队列上等待 [等待事件]。将工作描述符出列,对其进行操作,形成数据处理流水线_next_stage的描述符,并入队到下一个线程。我已经完成了许多 R/T 嵌入式系统来做这件事。 SCHED_RR 具有不同的优先级和保证的延迟/吞吐量,并且从未使用过sched_yield。这样做意味着对整个线程模型的错误设计。

标签: c multithreading linux-kernel posix scheduling


【解决方案1】:

Linus Torvalds' comment about sched_yield:

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

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

...

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

【讨论】:

  • 为了确保我明白,如果我按照 Linus 的想法,我永远不会使用sched_yield
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多