文章目录
基础知识
- 每个进程执行前,cpu需要知道任务从哪里开始加载,又从哪里开始运行,也就是说需要系统需要帮他保存这俩个值(cpu寄存器 and 程序计数器)
- cpu 寄存器: cpu内置的容量小,但是速度极快的内存
- 程序寄存器: 用来存储cpu正在执行的指令地址,或者下一条指令位置
- 由于他们都是cpu运行时候必须要的东西,所以叫做cpu执行上下文
cpu上下文切换
进程上下文切换
- 每次上下文切换都需要几十纳秒到数微秒的cpu时间,图片解释了为什么要几十纳秒的时间
- 什么时候会发生进程切换?
- cpu时间本身是一个个时间片,如果当前进程时间片执行完了则会挂起
- 当进程调用的系统资源不够的时候,比如内存
- 当进程通过sleep等函数
- 当有更高优先级进程运行时候
- 发生硬件中断的时候,会切换到内核中的中断服务
线程上下文切换
- 1.当进程只有一个线程的时候,可以认为进程就等于线程
- 2.当线程进行切换的时候,由于线程共享同一进程的虚拟内存和全局变量等资源,所以在上下文切换的时候是不需要修改的
- 3.另外线程自己也有自己的私有数据,比如栈和寄存器,这些在上下文切换的时候是需要保存的
中断上下文切换
- 1, 中断上下文也需要保存当前进程的上下文环境
- 2, 中断处理比进程拥有更高的优先级
- 3, 由1,2可得出,中断上下文过多的时候也会影响到cpu的性能
分析系统上下文切换的情况
查看系统上下文切换情况
# 每隔5秒输出1组数据
$ vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 7005360 91564 818900 0 0 0 0 25 33 0 0 100 0 0
- cs(context switch)是每秒上下文切换的次数。
- in(interrupt)则是每秒中断的次数。r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数。
- b(Blocked)则是处于不可中断睡眠状态的进程数
查看单个进程的上下文切换状态
# 每隔5秒输出1组数据
$ pidstat -w 5
Linux 4.15.0 (ubuntu) 09/23/18 _x86_64_ (2 CPU)
08:18:26 UID PID cswch/s nvcswch/s Command
08:18:31 0 1 0.20 0.00 systemd
08:18:31 0 8 5.40 0.00 rcu_sched
...
- cswch 表示自愿上下文切换(遇到I/O等情况,主动让出cpu)
- nvcswch 表示非自愿上下文切换(时间片到了,不得不让出cpu)
如果发现vmstat 的 cs 和 pidstata的 cswch 数据对不上
- 展示出进程中各个线程的情况,可能线程本身触发了很多次上下文切换
# 每隔1秒输出一组数据(需要 Ctrl+C 才结束)
# -wt 参数表示输出线程的上下文切换指标
$ pidstat -wt 1
08:14:05 UID TGID TID cswch/s nvcswch/s Command
...
08:14:05 0 10551 - 6.00 0.00 sysbench
08:14:05 0 - 10551 6.00 0.00 |__sysbench
08:14:05 0 - 10552 18911.00 103740.00 |__sysbench
08:14:05 0 - 10553 18915.00 100955.00 |__sysbench
08:14:05 0 - 10554 18827.00 103954.00 |__sysbench
...
ps: 参考书籍:《极客时间-Linux性能优化实战-倪朋飞》