跨进程如何保证线程调度的公平性?

How is fairness of thread scheduling ensured across processes?

每个进程至少有一个执行线程,我在某处读到现代操作系统只调度线程,进程。

因此,如果系统中有两个进程 运行 - P1 有 1 个线程,P2 有 100 个线程,OS 调度算法将如何确保 P1 和 P2 获得大致相同数量的线程CPU时间?如果 OS 盲目调度线程,P2 将获得比 P1 多 100 倍的 CPU 时间。

它是否也考虑了特定线程属于哪个进程?否则,进程似乎很容易通过创建更多线程来占用所有 CPU。

如果线程是调度的基本单位(目前通常是安全的假设),那么进程调度程序将决定分配给 CPU 的对象。它如何(以及是否)考虑线程使用完全是系统特定的。并且行为取决于过程的类型。例如,在 VMS 中(并在 Windoze 中采用)实时进程的处理方式与其他类型的进程不同。

在 VMS 类型的调度中,具有更多线程的进程在设计上获得更多 CPU。应用程序使用更多线程和使用更多进程更好。

请记住,系统可能会对进程中的线程数施加限制。

一般来说,"fair thread scheduling" 尝试给每个线程等量的 CPU 时间(不管一个进程中的所有线程获得多少 CPU 时间); "fair process scheduling" 尝试为每个进程提供相同数量的 CPU 时间(例如,通过为属于不同进程的线程提供不等量的 CPU 时间)。这些是相互排斥的 - 你不能同时拥有两者(除非每个进程都有相同数量的线程)。

请注意,无论如何这都是一个破玩笑。例如,如果一个线程在 CPU 上获得 10 毫秒的时间,由于热节流 运行 变慢(and/or 因为同一核心中的另一个逻辑 CPU 正忙) 并且另一个线程在 CPU 上获得 10 毫秒的时间,比正常情况下 运行 快(例如,由于 "turbo-boost" and/or 因为另一个逻辑 CPU核心未被使用);那么这些线程收到了等量的 CPU 时间,但没有收到任何可以被认为是 "fair" 的东西(因为一个线程可能能够完成比另一个线程多 20 倍的工作)。

请注意,无论如何这都是不需要的。例如,对于一个好的 OS 线程将被赋予优先级以表明它们所做的工作有多重要,而你不希望高优先级线程(做非常重要的工作)获得相同的 "fair share" 的 CPU 时间作为低优先级线程(做 irrelevant/unimportant 工作)。对于两个线程具有相同优先级的情况,您可能(理论上)希望它们获得 "equal" 数量的 CPU 时间;但在实践中这并不常见,线程阻塞和解除阻塞如此频繁以至于不值得关心;在实践中,它可能导致 "two half finished jobs instead of one completed job and one unstarted job" 场景,增加完成工作(例如工作请求)所需的平均时间。

Does it also take into account which Process a particular thread belong to? Otherwise, it seems too easy for a process to hog all the CPU by creating more threads.

错误的问题。考虑两个作业,它们试图通过做相同的工作来解决完全相同的问题,并且除了一件事之外完全相同——一个使用几十个线程,另一个使用几十个进程。为什么使用几十个进程的比使用几十个线程的获得更多CPU时间?

你的公平观念不是很明智。

相反,调度更多地围绕尝试在单位时间内完成尽可能多的工作而设计。假设计算机所做的一切都是有用的,并且让其他与之竞争的任务也尽快完成对竞争任务有利。

这实际上是绝大多数时间您所需要的。但有时您会遇到这种方法不起作用的特殊情况。一种是超高优先级任务,例如保持视频或音频流畅或保持用户界面响应。另一个是超低优先级任务,其中有大量您想要完成的工作,并且您不希望系统在您处理它时长时间运行缓慢。优先级用于此,通常系统允许高优先级线程中断低优先级线程以保持响应。