计算机操作系统--上下文切换

158 阅读4分钟

什么是上下文切换?

上下文切换(Context Switching) 是计算机操作系统中的一种机制,它允许多任务并发执行。在上下文切换过程中,操作系统会保存当前运行任务的状态(例如寄存器、程序计数器等),然后加载另一个任务的状态并开始执行。这样,每个任务都可以在一个独立的上下文中运行,从而实现多任务并发。

什么时候会发生上下文切换

  1. 阻塞:当一个进程因为某种原因(如等待用户输入、等待文件锁定等)而进入阻塞状态时,操作系统会将其挂起,然后将 CPU 分配给另一个进程。在这种情况下,需要进行上下文切换。
  2. 时间片耗尽:处理器以时间片轮转的方式为进程或线程分配CPU时间片,当时间片用完,当前运行的进程或线程就会被挂起,然后切换到下一个就绪的进程或线程执行。
  3. 抢占资源:当多个进程或线程竞争同一资源时,如果没有抢到资源的进程或线程会被挂起,让拥有资源的进程或线程继续执行。
  4. 状态切换:当一个进程或线程从用户态切换到内核态,比如进行系统调用、中断/异常/陷入,操作系统也会进行上下文切换。
  5. 优先级调度:当有优先级更高的进程或线程运行时,为了去运行高优先级的进程或线程,当前运行的进程或线程会被挂起。
  6. 进程间通信:当一个进程需要等待另一个进程发送数据或信号时,操作系统会将其挂起,然后将 CPU 分配给另一个进程。在这种情况下,需要进行上下文切换。
  7. I/O 操作:当一个进程或线程需要进行 I/O 操作时,如果等待数据,会被挂起以允许其他进程或线程继续执行。

上下文切换的类型

  • 对于Java的线程而言上下文切换可以分为两种类型:
    • 让步式上下文切换(Preemptive Context Switching):这是当一个执行线程主动释放CPU的情况,与锁竞争的严重程度成正比。。
    • 抢占式上下文切换(Non-preemptive Context Switching):在这种情况下,线程是因为分配的时间片用尽而被迫放弃CPU,或者被其他优先级更高的线程抢占了CPU。。

怎么减少Java中线程的上下文切换

  1. 减少锁竞争:锁竞争是导致让步式上下文切换的主要原因之一。可以通过使用更高效的数据结构、减少锁的粒度或使用无锁编程等方法来减少锁竞争,从而降低让步式上下文切换的发生概率。
  2. 减少线程数量抢占式上下文切换一般由于线程数大于CPU核心数引起。可以通过调整线程数量来降低其发生概率,例如使用线程池来管理和复用线程。
  3. 使用更快的算法和数据结构:优化算法和数据结构可以减少线程在执行计算和操作时的时间,从而减少上下文切换的次数。
  4. 避免长时间的阻塞操作:长时间的阻塞操作会导致线程挂起,增加上下文切换的次数。可以通过使用异步编程、非阻塞I/O等方式来避免长时间的阻塞操作。
  5. 使用适当的线程优先级:设置合适的线程优先级可以避免低优先级的线程被高优先级的线程频繁抢占,从而减少上下文切换的次数。
  6. 考虑使用协程或轻量级线程:协程或轻量级线程相比于操作系统原生的线程来说,上下文切换的开销更小。可以考虑使用协程或轻量级线程来替代传统的线程,以减少上下文切换的次数。