3

我在试图理解操作系统如何处理不同模型中的上下文切换,以便更好地理解为什么NIO性能在请求数量大峰值的情况下更好。除了线程数可能有限的事实之外,我很好奇在这些大量请求中阻塞操作是如何影响资源利用率的。睡眠/等待线程中的上下文切换

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

在此先感谢您的帮助。如果你能指向我的书籍,教科书等方向,我也会非常感激。

+0

核心上的CPU执行是由OS管理的资源之一。操作系统内核状态机已经知道哪些线程需要该资源,哪些线程不需要。如果一个线程请求I/O,并且请求不能立即得到满足,那么操作系统知道该线程不需要CPU资源,直到I/O请求得到满足,所以它不会给线程任何执行,直到它。杰里米的回答更详细。 – 2015-02-09 09:45:04

回答

7

如果499线程都在等待数据库IO,只有一个线程需要 工作,做了OS上下文切换所有500个线程 试图找到需要的工作之一之间?

如果操作系统的调度程序有一个健全的设计,迭代遍历整个系统的所有线程将会非常低效。

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

如果CPU很低,因为它大部分只是由交换 上下文而不是实际计算任何东西的IO成本所约束?

假设你没有用完RAM,没有涉及切换线程上下文的I/O;上下文切换仅涉及CPU和RAM。如果CPU使用率很低,最可能的原因是线程的算法本身是I/O限制的(例如,大多数情况下,大多数情况都在等待网卡或硬盘读取或写入数据)。如果您的线程实际上没有执行任何I/O操作,并且您仍然受I/O限制,这可能表示您的计算机已经用完了所有可用的RAM,并且不是一个好状态in。

+0

嗯'当应该唤醒线程的事件发生时'通常是'执行上下文切换'的时间。如果所有内核当前都运行高优先级的线程,那么这种线程不会立即在内核上运行的唯一原因。 – 2015-02-09 09:39:44

+0

是的,但我试图保持我的描述一般。 (作为一个反例,请注意,在两个线程设置为相同优先级的单核处理器上,上下文切换通常不会发生,直到第一个线程阻塞某个或其时间段过期) – 2015-02-09 15:38:30

+0

感谢这更清晰。 – JasonG 2015-02-09 20:01:08