软中断与硬中断

当iowait升高时,进程很可能因为得不到硬件的响应而长时间处于不可中断状态(D)。
进程的状态划分:

$ top 
PID USER   PR     NI   VIRT  RES     SHR    S %CPU %MEM TIME+ COMMAND
28961 root 20     0   43816  3148   4040    R  3.2 0.0 0:00.01 top 
  620 root 20     0   37280 33676    908    D  0.3 0.4 0:00.01 app 
    1 root 20     0  160072  9416   6752    S  0.0 0.1 0:37.64 systemd 
 1896 root 20     0       0     0      0    Z  0.0 0.0 0:00.00 devapp 
    2 root 20     0       0     0      0    S  0.0 0.0 0:00.10 kthreadd 
    4 root 0    -20       0     0      0    I  0.0 0.0 0:00.00 kworker/0:0H 
    6 root 0    -20       0     0      0    I  0.0 0.0 0:00.00 mm_percpu_wq 
    7 root 20     0       0     0      0    S  0.0 0.0 0:06.37 ksoftirqd/0

R:代表在cpu的就绪队列中,正在运行或者正在等待运行中
D:不可中断状态,代表进程正在跟硬件进行交互,并且交互过程中不允许被其他进程或者中断打断
Z:表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)
S:可中断状态睡眠,表示进程因为等待某个事件而被系统挂起,当进程等待的事件发生时,它会被唤醒进入R状态
I:空闲状态,用在不可中断的内核线程上。硬件导致的不可中断进程用D表示,但是对某些内核线程来说,实际上它们可能并没有任何负载,用 Idle 正是为了区分这种情况。要注意,D 状态的进程会导致平均负载升高, I 状态的进程却不会。
T或t:进程处于暂停或者跟踪状态,向一个进程发送 SIGSTOP 信号,它就会因响应这个信号变成暂停状态(Stopped);再向它发送 SIGCONT 信号,进程又会恢复运行(如果进程是终端里直接启动的,则需要你用 fg 命令,恢复到前台运行)。
而当你用调试器(如 gdb)调试一个进程时,在使用断点中断进程后,进程就会变成跟踪
状态,这其实也是一种特殊的暂停状态,只不过你可以用调试器来跟踪并按需要控制进程
的运行
X:进程已消亡

当系统或者硬件发生故障,进程可能在不可中断状态保持很久,甚至导致系统出现大量的不可中断进程

僵尸进程:正常情况下当一个进程创建子进程后,它应该通过系统调用wait()或者waitpid()等待子进程的结束,回收子进程的资源。而子进程在结束时,会向它的父进程发送sigchld信号,所以,父进程还可以注册sigchld信号的处理函数,来异步回收资源
如果父进程没这么做,或是子进程执行太快,父进程还没来得及处理子进程状态,子进程
就已经提前退出,那这时的子进程就会变成僵尸进程。换句话说,父亲应该一直对儿子负
责,善始善终,如果不作为或者跟不上,都会导致“问题少年”的出现。
通常,僵尸进程持续的时间都比较短,在父进程回收它的资源后就会消亡;或者在父进程
退出后,由 init 进程回收后也会消亡。
一旦父进程没有处理子进程的终止,还一直保持运行状态,那么子进程就会一直处于僵尸
状态。大量的僵尸进程会用尽 PID 进程号,导致新进程不能创建,所以这种情况一定要避

通过以下命令获取僵尸进程的信息:ps -A -ostat,ppid,pid,cmd |grep -e ‘^
[Zz]’,然后再通过pstree -aps < pid > 来查看父进程
在这里插入图片描述
ps指令中进程状态

$ ps aux | grep /app
2 root 4009 0.0 0.0 4376   1008 pts/0 Ss+ 05:51 0:00 /app
3 root 4287 0.6 0.4 37280 33660 pts/0 D+ 05:54 0:00 /app
4 root 4288 0.6 0.4 37280 33668 pts/0 D+ 05:54 0:00 /app

其中的s表示这个进程是一个会话的领导进程,+表示前台进程组
进程组表示一组相互关联的进程,比如每个子进程都是父进程所在组的成员
会话表示共享同一个控制终端的一个或者多个进程组

实战

$ top 
top - 05:56:23 up 17 days, 16:45, 2 users, load average: 2.00, 1.68, 1.39 
Tasks: 247 total, 1 running, 79 sleeping, 0 stopped, 115 zombie 
%Cpu0 : 0.0 us, 0.7 sy, 0.0 ni, 38.9 id, 60.5 wa, 0.0 hi, 0.0 si, 0.0 st 
%Cpu1 : 0.0 us, 0.7 sy, 0.0 ni, 4.7 id, 94.6 wa, 0.0 hi, 0.0 si, 0.0 st 
...
PID USER PR NI VIRT    RES SHR S %CPU %MEM TIME+ COMMAND 
4340 root 20 0 44676  4048 3432 R 0.3 0.0 0:00.05 top 
4345 root 20 0 37280  33624 860 D 0.3 0.0 0:00.01 app 
4344 root 20 0 37280  33624 860 D 0.3 0.4 0:00.01 app 
1    root 20 0 160072 9416 6752 S 0.0 0.1 0:38.59 systemd

从上图可以看出来:
1.负载持续升高并且1分钟平均负载已经到达系统的cpu个数,说明系统可能已经有了性能瓶颈
2.但僵尸进程比较多,而且还在不停增加,说明有子进程在退出时没被清理。
3.iowait较高
4.处于D状态的进程,它们可能在等待 I/O,但光凭这里并不能确定是它们导致了 iowait
升高。
说明:
第一点,iowait 太高了,导致系统的平均负载升高,甚至达到了系统 CPU 的个数。
第二点,僵尸进程在不断增多,说明有程序没能正确清理子进程的资源。

iowait分析
使用dstat命令查看cpu和io的情况:
在这里插入图片描述在这里插入图片描述
每次wai升高,read都会升高,也就是iowait升高跟磁盘读请求有关

软中断

中断是一种异步的事件处理机制,可以提高系统的并发处理能力
一次中断处理完之前,其他中断是不能响应的,所以就会造成其他中断丢失
为了解决中断处理程序执行过程和中断丢失的问题,linux将中断过程分为了两个阶段:
1.上半部分:用来快速处理中断,它在中断禁止模式下运行,主要处理跟硬件相关的时间敏感的工作
2.下半部分:用来延迟处理上半部分未完成的工作,通常以内核线程的方式运行
网卡在接收数据包后,会通过硬中断的方式,通知内核有新的数据包到了,这时候内核就应该调用中断处理程序来响应它,对于上半部分既然是快速处理中断,就是把网卡中的数据读到内存中,然后更新硬件寄存器的状态(表示数据已经读取好了),最后再发送一个软中断信号,通知下半部分做进一步处理。
而下半部被软中断信号唤醒后,需要从内存中找到网络数据,再按照网络协议栈,对数据
进行逐层解析和处理,直到把它送给应用程序。

所以,这两个阶段你也可以这样理解:
上半部直接处理硬件请求,也就是我们常说的硬中断,特点是快速执行;
而下半部则是由内核触发,也就是我们常说的软中断,特点是延迟执行。
实际上,上半部会打断 CPU 正在执行的任务,然后立即执行中断处理程序。而下半部以内
核线程的方式执行,
并且每个 CPU 都对应一个软中断内核线程,名字为 “ksoftirqd/CPU编号”,比如说, 0 号 CPU 对应的软中断内核线程的名字就是 ksoftirqd/0。
不过要注意的是,软中断不只包括了刚刚所讲的硬件设备中断处理程序的下半部,一些内核自定义的事件也属于软中断,比如内核调度和 RCU 锁(Read-Copy Update 的缩写,RCU 是 Linux 内核中最常用的锁之一)等。
当软中断事件频率过高的时候,内核也会因为cpu使用率过高而导致软中断处理不及时,进而引发网络收发延迟、调度缓慢等性能问题

查看软中断和内核线程
/proc/softirqs :提供软中断的运行情况
/proc/interrupts:提供硬中断的运行情况
下图显示的是不同类型的软中断在各个cpu下累计的运行次数
在这里插入图片描述
NET_TX:代表网络发送中断
NET_RX:代表网络接收中断

系统软中断cpu使用率升高的解决办法

# top 运行后按数字 1 切换到显示所有 CPU 
$ top
top - 10:50:58 up 1 days, 22:10, 1 user, load average: 0.00, 0.00, 0.00
Tasks: 122 total, 1 running, 71 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.0 us, 0.0 sy, 0.0 ni, 96.7 id, 0.0 wa, 0.0 hi, 3.3 si, 0.0 st
%Cpu1 : 0.0 us, 0.0 sy, 0.0 ni, 95.6 id, 0.0 wa, 0.0 hi, 4.4 si, 0.0 st
...
PID  USER PR NI   VIRT  RES   SHR S %CPU %MEM TIME+ COMMAND
7    root 20  0     0     0     0 S 0.3  0.0 0:01.64 ksoftirqd/0
16   root 20  0     0     0     0 S 0.3  0.0 0:01.97 ksoftirqd/1
2663 root 20 0 923480 28292 13996 S 0.3  0.3 4:58.66 docker-containe
3699 root 20  0     0     0     0 I 0.3  0.0 0:00.13 kworker/u4:0
3708 root 20  0 44572  4176  3512 R 0.3  0.1 0:00.07 top
1    root 20  0 225384 9136  6724 S 0.0  0.1 0:23.25 systemd
2    root 20  0     0     0     0 S 0.0  0.0 0:00.03 kthreadd

图中cpu使用率最高的都在软中断上,cpu0:3.3% cpu1:4.4%
而进程cpu使用率最高的也都是软中断进程,虽然都是0.3%

通过 watch -d cat /proc/softirqs 来观看软中断变化频率最快的中断类型

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值