陈同学
微服务
Accelerator
About
# Linux:CPU状态之us,sy,ni,id,wa,hi,si,st指标 > 本文转载自 **轩脉刃de刀光剑影** 的 [你不一定懂的cpu显示信息](https://www.cnblogs.com/yjf512/p/3383915.html) 和 **aCloudDeveloper** 的 [Linux探秘之用户态与内核态](https://www.cnblogs.com/bakari/p/5520860.html),笔者略有删减。 在服务端思维分享的 [一次应用 CPU 飙高的血案排查过程](https://mp.weixin.qq.com/s?__biz=MzA5NDg3MjAwMQ==&mid=2457102720&idx=1&sn=c89686c389d3372c044278143405e6ef) 一文中看到了利用CPU的 **st状态** 判断宿主机是否超卖,虽然常用top命令,但对CPU的us,sy,ni,id,wa,hi,si,st指标了解并不深,每次碰到不太了解的知识点就补一下。本次转载的文章用于学习这些状态的含义以及一些Linux用户态、内核态的概念。 下面是转载的文章。 ## 官方解释  * **us:** user cpu time (or) % CPU time spent in user space(用户态使用的cpu时间比) * **sy:** system cpu time (or) % CPU time spent in kernel space(内核态使用的cpu时间比) * **ni:** user nice cpu time (or) % CPU time spent on low priority processes(用做nice加权的进程分配的用户态cpu时间比) * **id:** idle cpu time (or) % CPU time spent idle(空闲的cpu时间比) * **wa:** io wait cpu time (or) % CPU time spent in wait (on disk)(cpu等待磁盘写入完成时间) * **hi:** hardware irq (or) % CPU time spent servicing/handling hardware interrupts(硬中断消耗时间) * **si:** software irq (or) % CPU time spent servicing/handling software interrupts(软中断消耗时间) * **st:** steal time - - % CPU time in involuntary wait by virtual cpu while hypervisor is servicing another processor (or) % CPU time stolen from a virtual machine(虚拟机偷取时间) ## 这个百分比是怎么算出来的? 比如一秒内有100个cpu时间片,这个cpu时间片就是cpu工作的最小单位。那么这100个cpu时间片在不同的区域和目的进行操作使用,就代表这个区域所占用的cpu时间比。也就是这里得出的cpu时间百分比。 比如下面一个程序:  将文件从磁盘的src位置拷贝到磁盘的dst位置。文件会从src先读取进入到内核空间,然后再读取到用户空间,然后拷贝数据到用户空间的buf上,再通过用户空间,内核空间,数据才到磁盘的dst上。 所以从上面这个程序来看,cpu消耗在kernel space的时候就是sy(系统态使用的cpu百分比),cpu消耗在user space的时候就是us(用户态使用的cpu百分比)。 ## hi和si 如果程序都没什么问题,那么是没有hi和si的,但是实际上有个硬中断和软中断的概念。比如硬中断,cpu在执行程序的时候,突然外设硬件(比如硬盘出现问题了)机器需要立刻通知cpu进行现场保存工作。这个时候会cpu会出现上下文切换。就是cpu会有一部分时间会被硬中断占用了,这个时间就是hi。相类似,si是软中断的cpu占用时间,软中断是由软件的指令方式触发的。 相关软中断和硬中断的概念可以参考:[计算机中断/硬中断/软中断之理解(1)](<http://blog.csdn.net/pxz_002/article/details/7327668>) ## ni ni是nice的意思,nice是什么呢,每个linux进程都有个优先级,优先级高的进程有优先执行的权利,这个叫做pri。进程除了优先级外,还有个优先级的修正值。即比如你原先的优先级是20,然后修正值为-2,那么你最后的进程优先级为18。这个修正值就叫做进程的nice值。 **那么nice是一个进程的优先级修正值,为什么会占用cpu时间呢?** ni是指用做nice加权的进程使用的用户态cpu时间比,我的理解就是一个进程的所谓修正值就意味着多分配一些cpu时间给这个进程的用户态,这个中间所多分配的cpu时间就是我们这里的ni。(这个理解没啥把握,如果有错误麻烦帮忙指出下) ## wa wa指的是CPU等待磁盘写入完成的时间,就是说前提是要进行IO操作,在进行IO操作的时候,CPU等待时间。比如上面那个程序,最后一步,从系统空间到dst硬盘空间的时候,如果程序是阻塞的,那么这个时候cpu就要等待数据写入磁盘才能完成写操作了。所以这个时候cpu等待的时间就是wa。 **所以如果一台机器看到wa特别高,那么一般说明是磁盘IO出现问题,可以使用iostat等命令继续进行详细分析。** ## st st的名字很生动,偷取。。。是专门对虚拟机来说的,一台物理是可以虚拟化出几台虚拟机的。在其中一台虚拟机上用top查看发现st不为0,就说明本来有这么多个cpu时间是安排给我这个虚拟机的,但是由于某种虚拟技术,把这个cpu时间分配给了其他的虚拟机了。这就叫做偷取。 ## id 剩下的id就是除了上面那么多cpu处理上下文以外的cpu时间片。当然在这些时间片上,cpu是空闲的。 top的所有这些cpu时间应该是相加为100%的。 ## 用户态与内核态 > 上面的us,sy指标涉及到用户态和内核态,这也是两个比较重要的概念。本小节内容来自 **aCloudDeveloper** 的 [Linux探秘之用户态与内核态](https://www.cnblogs.com/bakari/p/5520860.html),笔者略有改动。 <img width="30%" src="https://blog-1256695615.cos.ap-shanghai.myqcloud.com/2018/08/02/9a82846241864bbf8f20dc5e1135ef4b.png"/> 如上图所示,从宏观上来看,Linux操作系统的体系架构分为 **用户态和内核态(或者用户空间和内核)**。**内核**从本质上看是一种软件 —— **控制计算机的硬件资源**,并提供上层应用程序运行的环境。**用户态即上层应用程序的活动空间**,应用程序的执行必须依托于内核提供的资源,包括CPU资源、存储资源、I/O资源等。 ### 系统调用 为了使上层应用能够访问到内核提供的资源,内核必须为上层应用提供访问的接口:即系统调用。 系统调用是操作系统的最小功能单位,这些系统调用根据不同的应用场景可以进行扩展和裁剪,现在各种版本的Unix实现都提供了不同数量的系统调用。 ### 公共函数库 为了完成特定操作,必然会进行很多次系统调用,而**库函数**正是为了将程序员从复杂的细节中解脱出来而提出的一种有效方法。它**实现对系统调用的封装,将简单的业务逻辑接口呈现给用户,方便用户调用**。这样的一种组成方式极大增强了程序设计的灵活性,对于简单的操作,我们可以直接调用系统调用来访问资源,对于复杂操作,我们借助于库函数来实现。 ### shell Shell是一个特殊的应用程序,俗称命令行,本质上是一个命令解释器,它下通系统调用,上通各种应用,通常充当着一种“胶水”的角色,来连接各个小功能程序,让不同程序能够以一个清晰的接口协同工作,从而增强各个程序的功能。同时,Shell是可编程的,它可以执行符合Shell语法的文本,这样的文本称为Shell脚本,通常短短的几行Shell脚本就可以实现一个非常大的功能,原因就是这些Shell语句通常都对系统调用做了一层封装。为了方便用户和系统交互,一般,一个Shell对应一个终端,终端是一个硬件设备,呈现给用户的是一个图形化窗口。我们可以通过这个窗口输入或者输出文本。这个文本直接传递给shell进行分析解释,然后执行。 **总结一下,用户态的应用程序可以通过三种方式来访问内核态的资源:** * 系统调用 * 库函数 * Shell脚本 下图是对上图的一个细分结构,从这个图上可以更进一步对内核所做的事有一个“全景式”的印象。主要表现为:向下控制硬件资源,向内管理操作系统资源:包括进程的调度和管理、内存的管理、文件系统的管理、设备驱动程序的管理以及网络资源的管理,向上则向应用程序提供系统调用的接口。从整体上来看,整个操作系统分为两层:用户态和内核态,这种分层的架构极大地提高了资源管理的可扩展性和灵活性,而且方便用户对资源的调用和集中式的管理,带来一定的安全性。  ### 用户态和内核态的切换 因为操作系统的资源是有限的,如果访问资源的操作过多,必然会消耗过多的资源,而且如果不对这些操作加以区分,很可能造成资源访问的冲突。所以,为了减少有限资源的访问和使用冲突,Unix/Linux的设计哲学之一就是:**对不同的操作赋予不同的执行等级,就是所谓特权的概念**。简单说就是有多大能力做多大的事,与系统相关的一些特别关键的操作必须由最高特权的程序来完成。 Intel的X86架构的CPU提供了0到3四个特权级,数字越小,特权越高,Linux操作系统中主要采用了0和3两个特权级,分别对应的就是内核态和用户态。运行于**用户态的进程可以执行的操作和访问的资源都会受到极大的限制**,而运行在**内核态的进程则可以执行任何操作并且在资源的使用上没有限制**。很多程序开始时运行于用户态,但在执行的过程中,一些操作需要在内核权限下才能执行,这就涉及到一个从用户态切换到内核态的过程。比如C函数库中的内存分配函数malloc(),它具体是使用sbrk()系统调用来分配内存,当malloc调用sbrk()的时候就涉及一次从用户态到内核态的切换,类似的函数还有printf(),调用的是wirte()系统调用来输出字符串,等等。  到底在什么情况下会发生从用户态到内核态的切换,一般存在以下三种情况: 1. 当然就是系统调用:原因如上的分析。 2. 异常事件: 当CPU正在执行运行在用户态的程序时,突然发生某些预先不可知的异常事件,这个时候就会触发从当前用户态执行的进程转向内核态执行相关的异常事件,典型的如缺页异常。 3. 外围设备的中断:当外围设备完成用户的请求操作后,会像CPU发出中断信号,此时,CPU就会暂停执行下一条即将要执行的指令,转而去执行中断信号对应的处理程序,如果先前执行的指令是在用户态下,则自然就发生从用户态到内核态的转换。 注意:系统调用的本质其实也是中断,相对于外围设备的硬中断,这种中断称为软中断,这是操作系统为用户特别开放的一种中断,如Linux int 80h中断。所以,从触发方式和效果上来看,这三种切换方式是完全一样的,都相当于是执行了一个中断响应的过程。但是从触发的对象来看,系统调用是进程主动请求切换的,而异常和硬中断则是被动的。
本文由
cyj
创作,可自由转载、引用,但需署名作者且注明文章出处。
文章标题:
Linux: CPU状态之us,sy,ni,id,wa,hi,si,st指标
文章链接:
https://chenyongjun.vip/articles/64
扫码或搜索 cyjrun 关注微信公众号, 结伴学习, 一起努力