理解POSIX和Linux/glibc sched_*函数之间的差异

13

POSIX XSH 2.8.4 进程调度 定义了线程和进程调度属性的行为。 sched_* 接口被指定为影响进程的调度属性,而不是线程。以下文章对此进行了澄清:

  

POSIX模型将“进程”视为系统资源的聚合,包括一个或多个可以由操作系统在其控制的处理器上调度的线程。虽然进程具有其自己的调度属性集,但这些属性(如果有)对单个线程的调度行为具有间接影响,如下所述。

  

对于具有系统调度争用范围的线程,进程调度属性对线程或专用于该线程的底层内核调度实体的调度属性或行为均无影响。

我的理解是,在仅支持“系统调度争用范围”的系统(Linux / glibc是这样的系统)上,sched_ *函数应没有任何可观察到的影响。

这与Linux / glibc当前行为的现实相反,因为sched_ *设置了特定线程的调度属性。

除了一般上想更好地理解这种情况之外,我猜我有以下关键问题:

  1. 是否有任何关于此差异背后的理由的文档?

  2. 我对标准的理解是否正确? 特别是,我觉得很令人惊讶的是,在单线程应用程序(其中主线程使用默认调度策略(无法更改)和系统争用范围)中,sched_setparamsched_setscheduler将被指定为没有效果。

  • 标准的 sched_* 函数有什么用处?在大多数实现中,它们似乎没有影响,即使在支持进程争用范围的实现中,它们的影响也很小。请问有人可以描述它们的预期用途吗?


  • 3
    如果这不是 StackOverflow,这里可能就会引发一场口水战。 - ssice
    @ssice 这就是我们喜欢这里的原因 :) - Chen Li
    2个回答

    1
    我认为原因是自 NPTL 实现之前就已经这样了,没有人为内核贡献线程组范围的调度属性支持,所以这些函数仍然只执行它们一直在执行的操作。
    而且可能因为如你所指出的,如果没有进程争用范围,POSIX 指定的方式实际上并不是很有用...

    0

    sched_setparam等在Linux中的行为原理是,线程实际上是由clone(2)系统调用创建的进程,参见glibc/nptl/sysdeps/pthread/createthread.c


    2
    “线程实际上是进程”这句话是一个旧说法,实际上并不正确。进程是内核所称的“线程组”,它们与线程非常不同。然而,你所说的可能在这些接口被添加时仍然是“正确”的;让它们继续做错误的事情的理由可能只是现有应用程序的使用。然而,考虑到NPTL已经修复了LinuxThreads中大部分不正确的语义,这个问题没有被修复似乎有点奇怪... - R.. GitHub STOP HELPING ICE
    好的,那个措辞听起来不太好,虽然与LinuxThreads时代相比现在并没有更真实(或更虚假)。无论如何,在内核中没有明显的“只有一个线程的线程组”可调度实体,forkpthread_create都会到达内核中的相同的do_fork函数,该函数创建相同的struct task_struct实例。 - chill
    1
    我同意Linux中没有进程(线程组)的调度属性。这就是为什么NPTL省略了进程调度争用范围(顺便说一句,这是POSIX可选的)。我不理解的是,为什么这些函数会改变单个线程的调度属性,当它们似乎被规定为几乎不执行任何操作或完全不执行任何操作。 - R.. GitHub STOP HELPING ICE
    就内核而言(或至少是clone(2)手册),线程实际上只是一种进程,而POSIX所称的进程被称为线程组。 - SamB

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接