6

我试图了解操作系统如何处理不同模型中的上下文切换,以更好地理解为什么 NIO 性能在请求数量达到较大峰值的情况下会更好。除了线程数量可能有限制之外,我很好奇在大量请求中执行的阻塞操作如何影响资源利用率。

在每个线程一个请求的模型中,比如基于 servlet 2.5 的 Web 应用程序,如果 499 个线程正在等待数据库 IO 并且只有一个线程需要工作,操作系统上下文是否会在所有这 500 个线程之间切换,试图找到需要工作的线程? 为了执行上下文切换,操作系统必须存储当前线程的状态,并恢复下一个线程的状态。这样做之后,操作系统会发现它不需要任何 CPU 时间,并且会保持上下文切换,直到找到需要工作的线程。另外,这在服务器利用率方面是什么样的?CPU 是否低,因为它主要受交换上下文的 IO 成本的约束,而不是实际计算任何东西?

提前感谢您的帮助。如果你能指出书籍、教科书等的方向,我也会非常感激。

4

1 回答 1

17

如果有 499 个线程在等待数据库 IO 并且只有一个线程需要工作,操作系统上下文是否会在所有这 500 个线程之间切换,试图找到需要工作的线程?

如果操作系统的调度程序设计合理,则不会。一直迭代系统的所有线程将是非常低效的。

相反,大多数调度程序实现保留一个睡眠/阻塞线程列表和一个单独的“准备运行”线程列表。当发生应该唤醒线程的事件时(例如,传入数据在套接字或文件句柄上变得可用,或者线程被阻塞的互斥锁被释放),操作系统将该线程从睡眠/阻塞-线程列表到就绪线程列表。然后,当需要执行上下文切换时,操作系统从就绪线程列表中选择一个线程,加载该线程的上下文,并开始运行它。在任何现代/流行的操作系统中,睡眠/阻塞线程列表的大小对调度程序从就绪线程列表中选择一个线程运行所需的时间完全没有影响。(在某些操作系统下,就绪线程列表的大小可能会产生影响,但是一些调度器的设计使得即使是具有许多就绪线程的系统也不会导致调度器效率降低)

CPU 是否低,因为它主要受交换上下文的 IO 成本的约束,而不是实际计算任何东西?

假设您没有用完 RAM,则切换线程上下文不涉及 I/O;上下文切换仅涉及 CPU 和 RAM。如果 CPU 使用率低,最可能的原因是您的线程算法本身是 I/O 绑定的(例如,大多数情况下,大部分时间都在您的网卡或硬盘驱动器上等待读取或写入数据)。如果您的线程实际上不执行任何 I/O,并且您仍然受 I/O 限制,这可能表明您的计算机已用完其所有可用 RAM 并且正在抖动——这不是一个好的状态在。

于 2015-02-09T04:40:41.097 回答