概览图
中断
中断是什么意思
最初的中断指的是硬中断,也就是硬件中断,是由硬件触发的中断。
硬件向cpu的引脚发送信号,被称为是硬中断。
后来又有了使用软件来模拟硬中断的 软件中断。
中断的作用是什么
使进程从用户态 转换为 内核态。 内核态,是cpu运行操作系统内核的代码(内部包括进程调度之类的逻辑)。 用户态 是cpu运行用户进程的代码。
比较片面地来思考中断产生的原因:
其实可以思考这样的一个问题,就是 在只有一个cpu的情况下, cpu在执行一个进程,如果想要让cpu执行另外的进程,除了当前进程执行完成之外,还需要另外的手段来打断cpu的执行,使cpu执行判断程序,判断是否应该进行进程调度。
其实导致中断产生的原因还有很多,操作系统演化为多进程,由于各个硬件的访问速度差异很大,例如进程在等待io的时候,会消耗很多的时间,这个时候,可以让进程让出cpu的所有权,让cpu执行另一个进程,从而充分利用cpu的资源。
中断处理程序
cpu 收到中断后,根据中断的类型而 触发执行 对应的 中断处理程序。
每个中断都有对应的中断处理程序。
中断对应的中断处理程序分为上下两个部分,中断处理程序的下半部分就被称为是 软中断。
模糊概念区分: 软中断 硬中断 软件中断
硬中断:硬件触发的中断
软件中断:用软件模拟模拟硬件触发的中断
软中断:硬中断触发后,cpu所执行的中断处理程序的下半部分
触发中断后,谁(who) 会发生什么(what)
自己的理解,触发中断(硬中断或者软件中断)后,cpu进行上下文切换,执行中断处理程序。
中断处理程序执行完成之后,会如何?
中断处理程序执行完成后,cpu会再一次进行上下文切换,重新执行原来的进程。
中断(软件中断 硬中断)会带来的影响
中断会导致cpu上下文切换,cpu执行中断处理程序,会消耗cpu的资源。
硬中断
硬中断是什么
硬件触发的中断被被称为是硬中断,还可以这样认为,硬中断触发后 中断处理的上半部分。
硬中断的类型有哪些
- timer:时钟中断
- RES:重调度中断,用于唤醒空闲状态的 CPU 来调度新的任务运行。这是多处理器系统(SMP)中,调度器用来分散任务到不同 CPU 的机制,也被称为处理器间中断(Inter-Processor Interrupts,IPI) ......
硬中断与软中断的关系
这个问题,其实是想问,硬中断和软中断所发生的cpu位置是否是一样的。
触发硬中断 一定会触发软中断。在多核cpu的架构下,在某个cpu上触发的硬中断,必然会在这个cpu上执行软中断处理程序(也就是触发软中断)
硬中断与cpu (中断亲和性)
什么叫做 硬中断的cpu亲和性?
在多核cpu的架构下,硬中断在哪个cpu上触发(这个过程,就涉及到cpu亲和性)。
例如:
配置硬中断的cpu亲和性,使某个硬中断只会在某个cpu上触发,而不会在其他的cpu上触发。
Linux下 如何查看硬中断的 cpu亲和性?
执行:
cat /proc/irq/中断号/smp_affinity_list
smp_affinity_list 文件之中存储着 硬中断在哪些cpu上触发。
Linux下 为什么要调整 cpu的硬中断亲和性?
为了充分利用cpu。在多核cpu的架构下,如果某些中断只是会发生在某个cpu上,那么会导致cpu的资源利用不均衡
Linux下 如何调整cpu的硬中断亲和性?
修改 /proc/irq/中断号/smp_affinity_list 文件之中的值,来调整cpu的硬中断亲和性。
硬中断的触发会带来的影响?(会消耗计算机的哪些资源)
硬中断的触发会占据cpu资源。所以越多的硬中断的触发,就是消耗越多的cpu资源。对于程序员而言,希望cpu的资源更多地被用来执行我们的程序。 同时,硬中断资源占据的cpu资源多了,那么剩下的可供软件运行的cpu资源就少了。
硬中断的监控
对于硬中断的监控的目的是什么?
主要是为了查看 是否某个中断只是在单一的cpu上面发生(这样会导致cpu的资源利用不均匀,单个cpu出现瓶颈的问题),并且发生的次数非常多。
Linux下 如何查看硬中断在cpu上的分布?
执行一下命令:
cat /proc/interrupts
软中断
软中断是什么
软中断 是 中断处理程序的下半部分。
软中断所带来的影响是什么?
软中断会会消耗cpu资源。
软中断的监控
查看软中断在各个cpu上的分布
cat /proc/softirqs 输出信息
CPU0 CPU1 CPU2 CPU3
HI: 0 0 0 0
TIMER: 134061 26840 146766 31577
NET_TX: 2 0 0 1
NET_RX: 6020 1303 7543 1223
BLOCK: 0 0 0 0
IRQ_POLL: 0 0 0 0
TASKLET: 11 0 13 0
SCHED: 133601 27344 146478 31594
HRTIMER: 0 0 0 0
RCU: 101900 26048 106512 28531
备注:
NET_RX 网络收包中断
NET_TX 网络发包中断
观察 软中断 在 各个cpu上的分布情况的意义是什么?
目的是为了观察,软中断是否在cpu上分布不均,如果分布不均,那么就是出现了问题,是问题就需要进行处理。
在多核cpu下 是否可以控制软中断在哪个cpu上触发?如果可以,如何进行控制?
是可以的。 硬中断在哪个cpu上触发,软中断就会在哪个cpu上触发。所以只要控制硬中断的cpu亲和性,就可以控制 软中断在哪个cpu上发生。
在了解了中断的相关知识后,程序员可以将这些知识用在哪些地方,或者可以这样问,程序员为什么要了解中断?
因为中断会消耗cpu资源,会影响性能,所以程序员要了解中断。
如果中断分布不均,会导致系统资源很充裕的情况下,程序的执行出现资源缺乏导致性能问题。
所以程序员需要知道 查看 中断分布的方法。
这是自己目前的一些理解。
特殊的中断
时钟中断 与 进程调度
自己的目前的认知:
时钟中断触发 cpu执行对应的中断处理程序,而这一段中断处理程序之中包含是否进行进程调度的判断(例如当前进程的时间片是否耗尽检查)
时钟中断 与 时间片
时钟中断 与 节拍 相关。节拍就是 多久触发一次时钟中断。
时间片的长度 是 整数倍的 节拍。
Linux下 哪个硬中断是时钟中断
ubuntu
timer 是时钟中断
网络硬中断
Linux下 如何查看 哪个是网络硬中断
有的网卡会开启多队列,每个队列会对应一个硬中断号,硬中断号获取方式。
cat /proc/interrupts | egrep 'CPU|virtio.*(input|output)'
带有input的是 网卡收包的中断
带有output的是 网卡发包的中断
Linux下 网络硬中断对应的软中断号是哪个
cat /proc/softirqs
NET_RX 网络收包软中断
NET_TX 网络发包软中断
为什么会写 网络硬中断
因为程序员所编写的软件 几乎都是需要和网络进行交互的,所以网络硬中断会被大量触发,如果在cpu上分布不均匀,很容易会导致计算机的资源充足,但是程序出现性能问题。
软件中断
软件中断的概念
用软件来模拟硬件中断。
软件中断 是由 谁 进行触发的
系统调用
软件中断 与 系统调用
软件中断 与 系统调用的关系是什么?
系统调用其实是一条cpu指令,用来触发 cpu的中断。所以系统调用就是用软件来模拟硬件中断。所以 软件中断 其实就是系统调用。
硬中断触发后处理流程 vs 软件中断触发后处理流程
硬中断触发后处理流程
1: 外设将中断请求发送给中断控制器
2: 中断控制器根据优先级 有序地将中断传递给cpu
3: cpu终止执行当前程序流,触发cpu上下文切换
4: cpu根据中断号,从中断向量表之中找到对应的中断处理程序的执行地址,执行对应的中断处理程序(会分为两个部分,这里进行简化,假设只同步执行)
5: cpu进行上下文切换,返回原有的位置执行。
软件中断触发后处理流程 和硬中断处理流程的五步进程对比
1: 无
2: 无
3: cpu终止执行当前程序流,触发cpu上下文切换
4: cpu根据中断号,从中断向量表之中找到对应的中断处理程序的执行地址,执行对应的中断处理程序(会分为两个部分,这里进行简化,假设只同步执行)
5: cpu进行上下文切换,返回原有的位置执行。
其实只会执行三步。
一次中断 会 触发几次cpu上下文切换
会触发两次cpu上下文切换
cpu 上下文切换
什么是 cpu上下文切换?
如果要知道什么是 cpu上下文切换,必须首先知道什么是cpu上下文。
cpu上下文 是 cpu寄存器与程序计数器之中的内容,是一个程序运行所必须的内容。
cpu上下文切换 就是 替换cpu寄存器与程序计算器之中的内容。就是将原有的cpu上下文加载到内存之中,将新的任务的内容加载到cpu上下文之中。
为什么会产生cpu上下文切换 这个概念?
自己的理解: 要实现cpu 运行多个程序,必然是要实现cpu上下文切换的,这是程序运行需要cpu上下文 这个限制条件所导致的。
计算机之中是谁在执行 cpu上下文切换 这个任务呢?
是 cpu
哪些事件会触发 cpu上下文切换?
中断 会触发 cpu上下文切换。
更为具体的说,进程调度 系统调用 中断 会触发cpu上下文切换。
但是进程调度也是由中断触发的,系统调用其实是软件中断(用软件来模拟硬件中断)
cpu上下文切换的类别
根据计算机所执行的 任务 类别,来区分出不同的cpu上下文切换。
计算机所执行的任务除了 进程 和 线程之外,还有中断。
所以cpu上下文切换可以被分成 三个类别:
进程上下文切换 线程上下文切换 中断上下文切换
进程上下文切换
进程上下文切换 会 切换哪些资源
目前自己的理解:
进程上下文包括 用户空间 和 内核空间 两部分的资源。同时还会更新 cpu TLB(快表)的资源。
哪些行为会导致 进程上下文切换
进程调度的时候,会触发进程上下文切换。
有哪些情况会触发进程调度
- 1: 进程被分配的时间片耗尽
- 2: 进程执行完成
- 3: 进程在系统资源不足(例如内存不足)的时候会被操作系统挂起,然后由操作系统调度其他进程执行
- 4: 进程通过sleep之类的函数,主动将自己挂起,触发操作系统调度其他进程执行。
- 5: 有优先级更高的进程需要运行的时候,操作系统调度优先级更高的进程来执行。
线程上下文切换
线程上下文切换 会 切换哪些资源
如果切换的两个线程属于不同的进程,那么线程上下文切换所需切换的资源 和 进程上下文切换的资源是一致的。
如果切换的两个线程属于同一个进程,那么线程上下文切换所需的资源就仅仅是切换线程的私有数据、寄存器等不共享的数据。这样上下文切换的代价就小了。这就是多线程替换多进程的一个优势。
哪些行为会触发 线程上下文切换
进程调度 会 触发 线程上下文切换
中断上下文切换
中断上下文切换 会 切换哪些资源
所需切换的资源为:内核态中断处理程序所需执行所必须的状态。
哪些行为会触发中断上下文切换
硬中断 软件中断(系统调度)
进程上下文切换 线程上下文切换 中断上下文切换 三者之间的区别
三者其实是所要保存的上下文的内容不同,从这个角度上来思考即可。
cpu上下文切换监控
如何查看cpu上下文切换次数
使用vmstat 命令,查看系统整体的上下文切换次数情况
vmstat 1
// 每一秒输出一次信息
截图之中
cs字段的含义 时间间隔内上下文切换的次数。
in 字段的含义 时间间隔内中断发生的次数。
r 字段的含义 进程(或线程)就绪的数目
是否有方法区分 进程上下文切换次数 线程上下文切换次数 中断上下文切换次数
通过vmstat 可以获得中断的次数,以及cpu上下文切换的总次数。
cpu上下文切换的总次数 - 中断的次数 * 2 = 进程上下文切换次数+ 线程上下文切换次数。
自己目前没有办法获得 整个系统的进程上下文切换次数 以及 线程上下文切换次数。
如果 cpu上下文次数切换过多,会在哪个方面上表现出来?
如果cpu上下文次数切换过多,cpu的使用率会变高,cpu system字段的值会变得很高。
所以当cpu使用率很高,同时system字段的值很高的时候,可以使用vmstat 排查下,是否是cpu上下文切换的次数很多导致的。
cpu上下文切换次数过多,应该如何排查导致它的原因?
首先排查 是否是 大量的中断 导致的cpu上下文切换次数过多。
执行:
watch -d cat /proc/interrupts
监控硬中断之中变化最多的,看看是否是RES(进程调度中断)变化最多。如果是这个中断最多,那么是进程调度过多导致的cpu上下文切换次数过多。
如果 cpu上下文切换的总次数 - 中断的次数 * 2 还有很多,那么表示中断不是导致大量cpu上下文切换的元凶。
那么就从线程级别看下,是哪些线程产生了大量的上下文切换:
pidstat 命令来进行排查
执行
pidstat -wtu 1
获得线程级别的 上下文切换次数,以此来获得元凶,找出具体的原因。
cswch:表示每秒自愿上下文切换的次数
nvcswch:表示每秒非自愿上下文切换的次数
自愿上下文切换:
是指进程无法获取所需资源,导致的上下文切换。比如说, I/O、内存等系统资源不足时,就会发生自愿上下文切换。
非自愿上下文切换:
则是指进程由于时间片已到等原因,被系统强制调度,进而发生的上下文切换。比如说,大量进程都在争抢 CPU 时,就容易发生非自愿上下文切换。
程序员了解 cpu上下文切换的意义是什么,对于写代码而言有什么帮助
自己目前的认知,就是在 程序出现性能瓶颈(cpu使用率飙升的时候),能够让程序员有排查的思路,当程序员的思维之中有 一个认知,大量的cpu上下文切换是会导致 cpu的使用率飙升,那么真的遇到这样的问题的时候,便可以着手进行排查。
Linux下模拟不同类型的进程
Linux下模拟cpu密集型进程
stress -i 1 --timeout 600
Linux下 模拟 io密集型进程
stress -i 1 --timeout 600
Linux下 如何模拟多进程(线程)大量调度的情况
写个 java 多线程程序 然后使用 Thread.yeild()来触发线程调度
cpu监控
如何看待cpu监控这件事情
监控的目的,是监控资源的使用。对于cpu的监控,其实是监控cpu资源的监控。了解cpu资源的使用状况,了解是谁在使用cpu资源。
Linux 与 cpu
Linux 是如何抽象cpu的(Linux是如何将cpu抽象成资源的,或者说cpu资源是什么)
自己目前的理解: 将cpu的一段时间(例如一秒)分成许多个小的片段(时间片),这些时间片就是cpu资源,代表着cpu的执行时间。哪个进程获得了时间片,代表着拥有一段时间的cpu执行时间。cpu的执行时间,就是cpu的资源。对于单核cpu而言,同一时刻只能运行一个程序。
Linux下cpu的监控指标有哪些
- cpu平均负载
- cpu使用率
cpu平均负载
什么是cpu平均负载
单位时间内 处于 活跃状态和不可中断睡眠状态的 平均进程数。
所以简单地理解:cpu平均负载就是 平均进程数(处于活跃状态和不可中断状态)
活跃状态:处于运行状态或者处于就绪状态,等待被cpu调度执行的进程。
不可中断睡眠状态:进程正在和硬件进行交互,交互过程不能被其他进程或中断打断(并不会占据cpu,只是强调不能被打断。)
备注:处于不可中断睡眠状态的进程 会被 操作系统挂起。
cpu平均负载的统计规则
单位时间内 处于 活跃状态和不可中断状态的 平均进程数。
评价 cpu平均负载 这个指标是否过高的标准
首先查看当前服务器上的逻辑cpu的个数,如果cpu平均负载的值超过逻辑cpu数目的70%,那么cpu平均负载这个指标过高。
Linux下 如何查看cpu负载
执行命令 uptime
备注:load average 后面的三个数字,分别表示 过去一分钟 过去五分钟 过去十五分钟内的cpu平均负载。
cpu平均负载的意义是什么?数字的背后折射出什么?程序员应该带着怎么样的思绪来看待这个指标?
当cpu平均负载这个值过高,那么表示系统的资源存在一定的瓶颈,需要着手排查具体的原因。
如果cpu平均负载这个指标升高了,
可能是硬件出现了问题,导致 处于不可中断睡眠状态的进程数目增多了,导致cpu平均负载升高,
还可能是存在大量的进程(线程) 等待调度。
还有可能是上面两种情况一起出现。
cpu平均负载 是否和 cpu使用率 有着联动的关系,就是cpu负载越高,cpu使用率越高?
不一定。 要分情况来讨论。
对于cpu密集型进程而言,cpu使用率很高的同时,cpu平均负载也会很高。
对于io密集型的进程而言,cpu使用率不一定很高,但是cpu平均负载会很高。
存在大量进程调度情况的时候,cpu的使用率很高的同时,cpu平均负载也会很高。
注意:
cpu使用率很高,但是cpu平均负载不一定高。两个指标并没有很强的关联性。
cpu平均负载很高的时候,应该如何排查?
1:首先排查服务器上是否存在大量进程调度的情况。 执行vmstat,查看 r字段的值 是否远远超过cpu的逻辑核数。
2:排查是否是硬件导致的cpu平均负载很高。
执行
mpstat -P ALL 3 1
命令的含义:三秒后 输出一组cpu的使用数据。
重点查看 %iowait字段,如果这个字段很高,那么表示是io等待导致的cpu平均负载很高的问题。
那么如何排查,是哪个进程存在大量的io等待呢?(将问题定位到具体的进程)
执行
pidstat -u 3 1
命令的含义:三秒之后输出一组数据,显示进程的cpu占用。
可以通过观察 %CPU 这个指标来查看是哪个进程消耗大量的cpu的。
3:排查是否存在cpu密集型的进程,导致cpu平均负载很高
执行
pidstat -u 3 1
命令的含义:三秒之后输出一组数据,显示进程的cpu占用。
cpu 使用率
cpu使用率的含义是什么?
自己的理解:就是一段时间内 cpu的使用状况。在这段时间内,cpu的运转状况。
Linux 与 cpu使用率
cpu使用率的统计方式
首先要确认,cpu使用率统计程序是在什么时候执行的。
cpu使用率统计程序是在 时钟中断处理程序之中被执行的。
将cpu的使用率分为 us ni sys hi si wa st id 这几种类别。
消耗在某种状态下的cpu时间 / 总时间 = 某种状态的cpu使用率。
cpu us字段
进程用户态所占据的cpu时间比例。(这里所统计的进程指 nice值小于等于0的进程)
cpu ni 字段
进程用户态所占据的cpu时间比例。(这里所包含的进程,是指 nice值大于0的进程。)
Linux下 使 ni字段的值 飙升的方式
定义一个无限循环的程序, nice -n 正数 运行程序。 然后就可以看到 cpu nice字段的使用率飙升。
cpu sys 字段
进程处于内核态所占据的cpu时间比例(除去硬中断 软中断)
哪些行为会占据 cpu sys字段
cpu上下文切换
中断处理程序的执行
...
cpu hi 字段
进程处于硬中断所占据的cpu时间比例。(硬中断,也是处于内核态的一种,只是不被统计进入sys字段而已)
cpu si 字段
进程处于软中断所占据的cpu时间比例。(软中断,也是处于内核态的一种,只是不被统计进入sys字段)
Linux 如何模拟 si飙升的情况
1:docker run -itd --name=nginx -p 80:80 nginx 2:hping3 -S -p 80 -i u100 ip地址 通过发送大量的网络包,触发硬中断,触发软中断,来使cpu si 飙升。
si字段的值 飙升背后的含义
cpu 花费大量的时间在si上。表示大量的软中断被触发。 如果软中断在cpu上分布不均匀的话,那么会出现问题。 这是需要关注软中断的真实原因。
cpu wa 字段
wa的定义是 在cpu处于空闲状态时,会检查是否有阻塞的io,如果有的话,会记入wa。
其实可以想下,如果io压力很大,所有的进程都在等待cpu,那么cpu的时间片就找不到进程了。
所以这段时间其实就是相当于花费在了iowait上。
Linux下模拟使 wa字段的值 飙升的简单命令
stress -i 2 --timeout 500
如何看待所观察到 wa 字段的值很高,背后的含义
1:wa 飙升,表示 系统的io压力 逐渐变大。 2:可能是 磁盘等硬件设备出现了损坏
cpu steal 字段
虚拟cpu等待的时间
cpu id 字段
cpu处于空闲状态所占据的cpu时间的比例。
Linux下 如何查看 cpu使用率
top 命令来查看 Linux系统级别 cpu的使用状况。
注意:top命令默认的时间间隔是3秒
Linux下 哪些行为会消耗cpu的资源
自己目前的理解:
中断 以及 程序的运行 会消耗cpu的资源。
Linux下 如何查看 进程对于cpu资源的消耗情况
使用pidstat 命令来查看 进程级别 对于 cpu资源的使用情况
执行:
pidstat 1 5
命令含义:每隔一秒输出一次 进程对于cpu资源的使用情况,一共输出五次。
Linux下 cpu使用率过高,应该如何去排查
排查的思路就是:
首先看是cpu使用率的哪个字段的值过高。
如果是us字段过高,那么使用pidstat查看进程级别对于cpu资源的使用情况,查看是否是由某个进程导致的。
如果是sys字段的值过高,那么使用 vmstat 查看 系统整体上的上下文切换次数,以及使用pidstat 来查看线程级别的上下文切换次数,来找出是哪个进程导致的。
如果是wa字段的值过高,那么表示是系统的io压力很大,瓶颈在于io,使用pidstat 找出是哪个进程的io压力很大,然后进行分析。
如果是si字段的值很高导致的,那么表示大量的软中断触发导致cpu资源的大量使用。可以查看 /proc/softirqs 文件之中的数据,来找出是哪一种软中断大量触发,然后来进行分析。
如果是hi字段的值很高,背后的含义是大量的硬中断占据着cpu资源,可以架空 /proc/interrupts 文件之中的数据,来判断是哪个硬中断在大量触发。
如果ni字段的值很高,那么就表示 nice值大于0的进程在占据大量的cpu,使用pidstat 查看进程级别的cpu使用状况即可。
找到了是哪个进程导致的cpu使用率飙升,如何发现具体是哪一行代码导致的呢?
使用perf 命令来观察具体的问题代码行数:
perf top -g -p 进程id
如果系统的cpu使用率很高,但是按进程分析,却没有一个进程的cpu使用率很高的时候,应该采取什么样的方式来排查?
这个问题可能是短时应用导致的。大概是 应用之中调用了其他二进制应用,这些程序通常运行的时间比较短,通过top等工具也不容易发现。
可以使用 execsnoop 命令来排查是否是短时应用导致的cpu使用率飙升。
或者可能是某个进程不断崩溃又重启,导致的大量cpu消耗。