上下文切换

即,不同线程之间的切换。
是存储和恢愎CPU 状态的过程,它使得线程执行能够从中断恢愎执行。
上下文切换是需要开销的。

线程切换只在多核 CPU 中才有

并不是,线程切换是CPU的功能,单核 CPU 也可以进行上下文切换。
CPU 执行线程的粒度是通过给分个线程分配时间切片来实现的。在单核时代,一个系统也会开很多程序,每个程序都会等待CPU来执行并不会等会某一个线程执行完毕。
比如单核时代玩 CS,可以边玩游戏边听千千静听。

CPU 通过切换时间分片来执行任务,切换前都会保存上一次任务的状态,这样下次再切回来的时候,可以继续执行当前这个状态。
这种保存再切换回来的操作,就是一次上下文切换

查看上下文切换

在linux下,使用vmstat 进行查看:

执行:

1
vmstat 10 10

查看一下结果:

1
2
3
4
5
6
7
8
9
10
11
12
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
16 0 0 221468 41628 19576852 0 0 328 145 0 0 1 0 99 0 0
0 2 0 222260 41748 19564900 0 0 292478 15765 14014 14467 5 1 84 10 0
1 1 0 266040 41764 19512824 0 0 289173 18031 16546 11848 7 1 83 9 0
3 0 0 230408 41636 19525744 0 0 293228 13974 16831 12866 6 1 83 10 0
0 1 0 235068 41636 19497308 0 0 289227 17846 17284 13136 6 1 83 10 0
0 2 0 247768 41536 19484392 0 0 297066 10654 16103 12549 3 1 85 11 0
1 3 0 222212 41776 19476168 0 0 285245 22050 17815 13645 5 1 83 11 0
0 1 0 225332 41584 19473580 0 0 295298 11009 15639 15600 3 1 82 15 0
0 8 0 221040 40884 19477252 0 0 304033 5120 13754 13055 2 1 86 12 0
1 1 0 227988 40440 19432700 0 0 296429 9154 15598 16809 4 1 82 13 0

如何减少上下文切换

既然上下文切换会导致额外的开销,因此减少上下文切换次数便可以提高多线程程序的运行效率。

减少上下文切换的方法有:

  1. 无锁并发编程
  2. CAS算法
  3. 使用最少线程和使用协程
  4. 协程,go 当中使用