线程调度间的上下文切换

线程调度间的上下文切换

什么是上下文切换?

如果主线程是唯一的线程,那么他基本上不会被调度出去。另一方面,如果可运行的线程数大于CPU的数量,那么操作系统最终会将某个正在运行的线程调度出去,从而

使其他线程能够使用CPU。这将导致一次上下文切换。在这个过程中将保存当前运行线程的执行上下文,并将新调度进来的线程的执行上下文设置为当前上下文。

切换上下文需要一定的开销,而在线程调度过程中需要访问操作系统和JVM共享的数据结构。应用程序、操作系统以及JVM都使用一组相同的CPU。在JVM和操作系统的代码中消耗越多的CPU时钟周期,应用程序的可用CPU时钟周期就越少。但上下文切换的开销并不只是包含JVM和操作系统的开下。当一个新的线程被切换进来时,它所需要额数据可能不在当前处理器的本地缓存中,因此上下文切换将导致一些缓存缺失,因而线程在首次调度运行时会更加缓慢。这就是为什么调度器会每个可运行的线程分配一个最小执行时间,即使有许多其他的线程正在等待执行:它将上下文切换的开销分摊到更多不会中断的执行时间上,从而提供整体的吞吐量(以损失响应性为代价)。

当线程由于等待某个发生竞争的锁而被阻塞时,JVM通常会将这个线程挂起,并允许它被交换出去。如果线程频繁的发生阻塞,那么他们将无法使用完整的调度时间片。在程序中发生越多的阻塞(包括阻塞IO,等待获取发生竞争的锁,或者在条件变量上等待),与CPU密集型的程序就会发生越多的上下文切换,从而增加调度开销,并因此降低吞吐量。(无阻塞算法同样有助于减小上下文切换)

上下文切换的实际开销会随着平台的不同而变化,然而根据经验来看:在大多数通用的处理器中,上下文切换的开销相当于5000-10000个时钟周期,也就是几微秒。

UNIX系统的vmstat命令和Windows系统的perfmon工具都能报告上下文切换的次数以及在内核中执行时间所占比例等信息。如果内核占用率较高(超过10%),那么通常表示调度活动发生的很频繁,这很可能是由于IO或竞争锁导致的阻塞引起的。

======END=======

你可能感兴趣的:(线程调度间的上下文切换)