上下文切换睡眠/等待线程

时间:2015-02-08 22:23:12

标签: multithreading threadpool nonblocking context-switch context-switching

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

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

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

1 个答案:

答案 0 :(得分:11)

  

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

如果操作系统的调度程序具有合理的设计,则不会;迭代遍历所有系统的线程,所有时间都非常低效。

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

  

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

假设您没有用完RAM,切换线程上下文时不会涉及I / O.上下文切换仅涉及CPU和RAM。如果CPU使用率很低,最可能的原因是你的线程'算法本身受I / O限制(例如,大多数情况下,大多数所有内容都在等待您的网卡或硬盘驱动器读取或写入数据)。如果您的线程实际上没有进行任何I / O,并且您仍然受到I / O限制,那么这可能表示您的计算机已耗尽其所有可用内存并且thrashing - 不是一个好的状态。