1.指标范围1.1用户态CPU利用率+系统态CPU利用率合理值:60-85%。如果在多用户系统中us+sy时间超过85%,进程可能会在运行队列中等待,响应时间和业务吞吐量都会受损;如果us太大,说明用户进程占用cpu时间多,需要进一步分析其他软硬件因素;如果sy太大,说明系统管理很费时间。耗时较长,说明系统中某个子系统存在瓶颈,需要进一步分析其他软硬件因素。1.2wa(wait)参考值:小于25%,wa值超过25%可以说明子系统可能没有适当平衡,也可能是磁盘密集型工作负载的结果,系统的磁盘或其他I/O可能有问题1.3id(idle)参考值:大于40,如果r经常大于4,id经常小于40,说明CPU负载很重1.4r参考值:小于4、queue当大于4时,说明系统的CPU或内存可能有问题。如果r经常大于4,id经常小于40,说明CPU负载过重。当队列变长时,队列中的进程等待cpu调度执行的时间就会变长。1.5判断cpu瓶颈的方法很慢。用户cpu时间过长(用户cpu百分比过高)系统cpu时间过长(系统cpu百分比过高)运行进程队列过长(运行队列大小持续时间过长)2.如何查看cpu利用率2.1使用top命令查看/proc/stat文件中的数据%us=(Usertime+Nicetime)/CPU时间*100%%sy=(Systemtime+Hardirqtime+Softirqtime)/CPU时间*100%%id=(Idletime)/CPU时间*100%%ni=(Nicetime)/CPU时间*100%%wa=(Waitingtime)/CPU时间*100%%hi=(Hardirqtime)/CPU时间*100%%si=(Softirqtime)/CPU时间*100%%st=(Stealtime)/CPU时间*100%备注:top命令默认3秒刷新一次。也可以使用top-d来指定刷新频率,比如top-d0.1或者top-d0.01。执行top时,也可以按“s”键修改时间间隔。2.2使用vmstat查看r表示运行队列大小,b表示IO等待线程数,in表示中断数,cs表示上下文切换数。2.3其他查看方法如iostat、sar-q、sar-u等。3.CPU介绍3.1内核HZ中的时间是系统时钟在一秒内发送时钟中断的次数。HZ可以在编译内核之前配置,所以可以通过以下命令查看当前系统的时钟中断频率:cat/boot/config-`uname-r`|grepCONFIG_HZtick是系统时钟每“滴答”的时间,其值为(1/HZ)秒。即连续两次时钟中断之间的时间间隔。jiffies是用来统计自系统启动以来的滴答次数,也就是说,系统时钟每产生一次时钟中断,这个变量的值就会增加一次。3.2CPU时间的构成CPU工作时间由三部分组成:用户态时间、系统态时间和空闲态时间。具体构成为:CPU时间包括Usertime、Systemtime、Nicetime、Idletime、Waitingtime、Hardirqtime、Softirqtime、StealtimeIdlestatetime==idletimeUserstatetime==usertime+Nicetime。内核态时间==系统时间+Hardirq时间+Softirq时间。用户时间。指CPU在用户态执行进程的时间。系统时间。指CPU在内核中运行的时间。美好的时光。指系统花在调整进程优先级上的时间。空闲时间。系统空闲,等待进程运行。等待的时间。指CPU等待I/O操作的总时间,类似于ed。偷时间。指当前CPU被迫(非自愿等待)等待另一个虚拟CPU完成处理所花费的时间。此时,管理程序正在为另一个虚拟处理器服务。Softirq时间,Hardirq时间。对应系统在处理软中断和硬中断时消耗的CPU时间。3.3用户态CPU利用率%usr。显示在用户模式下花费的CPU时间百分比。用户使用CPU的进程包括:cpu运行普通用户进程,cpu运行niced进程,cpu运行实时进程。进程可以在用户模式或系统(内核)模式下执行。当一个进程运行在内核代码中时,我们称它为内核态;当一个进程正在执行用户自己的代码时,我们称它为用户态。在用户模式下执行时,进程在自己的应用程序代码中执行,不需要内核资源来执行计算、管理内存或设置变量。3.4SystemmodeCPUutilization显示cpu在系统模式下花费的时间百分比,包括内核进程(kprocs)和其他需要访问内核资源的进程消耗的cpu资源。系统使用cpu的进程包括:用于系统调用,用于I/O管理(中断和驱动),用于内存管理(分页和交换),用于进程管理(上下文切换和进程启动),如果一个进程需要一个内核资源,它必须执行系统调用,从而切换到系统模式以使资源可用。3.5%wa(wait)显示挂起的本地磁盘I/O和NFS加载的磁盘的cpu空闲百分比。它是由于进程等待I/O而导致cpu处于空闲状态的比率。I/O主要包括:I/O、rawI/O、VM-paging/swapins。如果在wait运行时至少有一个未完成的磁盘I/O,事件被归类为I/O等待时间,对磁盘的I/O请求将导致调用进程阻塞(或休眠)直到请求完成了。一旦进程的I/O请求完成,进程就会被放入运行队列。如果I/O完成得很快,进程可以使用更多的CPU时间。3.6%id(idle)除了上述WIO空闲情况外,它还显示了当没有本地I/O时cpu空闲或等待的时间百分比。如果没有线程可以执行(运行队列为空),系统会调度一个名为wait的线程,这个线程可以称为idlekproc。如果ps报告显示此线程的总时间较长,这表明有一段时间没有其他线程准备好在cpu上运行或等待执行。因此,系统大部分时间处于空闲状态或等待新任务。3.7r(runq-sz)运行进程队列的长度。对于处于runnable状态的进程数的大小,这些进程在内存中就绪4.概念介绍4.1用户态+内核态可以运行在内核态,运行在内核态(即进程分别工作在用户态和内核态,内核态下工作的仍然是进程,除非进程被切换)。通常操作系统将虚拟地址空间分为用户空间和内核空间。比如Linux系统在x86平台上的虚拟地址空间是0x00000000~0xffffffff,前3GB(0x00000000~0xbfffffff)是用户空间,后1GB(0xc0000000~0xffffffff)是内核空间。用户加载到用户空间并在用户模式下执行。它不能访问内核中的数据,也不能跳转到内核代码执行。这样可以保护内核。如果一个进程访问了一个非法地址,最多这个进程会崩溃,不会影响内核和整个系统的稳定性。当CPU产生中断或异常时,它不仅会跳转到中断或异常服务中心,还会自动从用户态切换到特权模式,这样中断或异常程序就可以跳转到内核代码执行。事实上,整个内核就是由各种中断和异常处理程序组成的。即正常情况下,处理器在用户态执行用户程序,遇到中断或异常时,处理器切换到特权模式执行内核程序,然后返回用户态继续执行用户程序在处理完中断或异常后,例如用户进程A调用内核系统调用获取当前的时钟滴答数。当执行用户进程A中的系统调用指令时,会保存当前用户进程的IP、CS等当前状态,然后跳转到内核空间(即内核代码区)去执行相应的系统调用函数以获取当前时钟节拍号。执行完后,通过IRET指令返回到进程A(也就是把进入时保存的信息复位到相应的寄存器),然后从CS:EIP地址开始执行A进程的指令。创建进程时,除了创建进程的控制块外,还会在内核中创建进程的内核栈。进程通过系统调用(如fopen()或open())进入内核后,处理器在特权级最高层(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈,它指向进程的上下文。内核态的权限高于用户态。允许。用户级别。系统用户可以与系统进行交互,如运行应用程序和系统命令,用户层通过系统调用接口访问内核层;内核级别。操作系统自动运行一些功能,它们主要对硬件进行操作。4.2进程调度任何进程想要占用CPU并且实际处于执行状态,都必须通过进程进行调度。进程调度机制主要涉及调度方法、调度时机和调度策略。1、调度方式Linux内核的调度方式基本上采用“抢占式优先”的方式,即当一个进程运行在用户态时,无论是否自愿,在一定条件下(如时间片运行outorwaitingforI/O),核心可以暂时剥夺它的运行并安排其他进程运行。但是,一旦进程切换到内核态运行,就会不受上述限制继续运行,直到返回用户态才会发生进程调度。Linux系统中的调度策略基本上继承了Unix的基于优先级的调度。也就是说,内核会为系统中的每个进程计算一个优先级,它反映了一个进程是否有资格获得CPU使用权,即优先级高的进程先运行。内核从进程就绪队列中选择一个优先级最高的进程,为其分配一个CPU时间片,并投入运行。在运行过程中,当前进程的优先级随着时间的推移而递减,实现了“负反馈”的效果:经过一段时间后,原来较低级别的进程在级别上相对“提升”,从而有机会被运行。当所有进程的优先级都变为0时,重新计算所有进程的优先级。2.调度策略Linux系统针对不同类型的进程提供了三种不同的调度策略,即SCHED_FIFO、SCHED_RR和SCHED_OTHER。SCHED_FIFO适用于实时进程。他们对时间要求很强,每次跑完需要的时间都比较短。一旦这样的进程被安排开始运行,它就必须一直运行,直到CPU被自动放弃,或者优先级被改变。高进程抢占它的执行权。SCHED_RR对应“时间片轮转法”,适用于每次运行时间较长的实时进程。一个正在运行的进程会分配一个时间片(比如200毫秒)。当时间片用完后,CPU被另一个进程抢占,该进程被送回同一优先级队列的尾部。SCHED_OTHER是一种传统的Unix调度策略,适用于交互式分时进程。此类进程的优先级取决于两个因素。一个因素是进程的剩余时间配额。如果进程用完分配的时间,对应的优先级为0;另一个是nice进程的优先级数,它继承自Unix系统。对于down方法,优先级数字越小,优先级越高。nice的取值范围是19-20。用户可以使用nice命令设置进程的nice值。而普通用户只能设置正值,主动降低优先级;只有特权用户才能将nice的值设置为负数。进程的优先级是以上两者之和。内核动态调整用户态进程的优先级。这样,一个流程完成任务后,从创建到终止,需要经过多次反馈循环。当进程计划再次运行时,它会从中断处恢复执行。对于实时进程,优先级的值为(1000+设置的正值),因此,至少为1000。因此,实时进程比其他类型的进程具有更高的优先级。另外,时间配额和nice值与实时进程的优先级无关。如果系统中有实时进程处于就绪状态,则非实时进程不能被调度运行,直到所有实时进程都完成,非实时进程才有机会占用中央处理器。后台命令(在命令末尾带有&符号,例如gccf1.c&)对应于后台进程(也称为后台作业),其优先级低于任何交互式(前台)进程。因此,只有当系统中当前没有可运行的交互进程时,后台进程才会被调度运行。后台进程通常被安排成批运行。3、调度时序内核调度进程的时序有以下几种情况:(1)当前进程调用系统调用nanosleep()或pause()使自己进入休眠状态,主动放弃CPU使用权一段时间;(2)进程终止,绝对放弃CPU的使用;(3)时钟中断处理程序执行过程中,发现当前进程连续运行时间过长;(4)当唤醒一个休眠进程时,发现被唤醒的进程比当前进程更有资格运行;(5)进程通过执行系统调用改变调度策略或降低自身优先级(如nice命令),从而引起立即调度。4.调度算法进程调度的算法应该比较简单,以减少频繁调度时的系统开销。Linux在执行进程调度时,首先查找就绪队列中的所有进程,选择一个优先级最高且在内存中的进程。如果队列中有实时进程,则实时进程先运行。如果最需要运行的进程不是当前进程,则挂起当前进程,并保存其站点涉及的所有机器状态,包括计数器和CPU寄存器等,然后选择的进程恢复运行地点。4.3用户级线程和内核级线程在很多类Unix系统中,如Linux、FreeBSD、Solaris等,进程一直是操作系统内核调用的最小单位,多进程模型也是采用。后来引入了线程的概念,线程有两个概念:用户级线程(User-LevelThread,ULT)。由应用进程使用线程库创建和管理,线程没有在内核中实现,只是在用户态模拟多线程,不依赖于内核,操作系统内核完全不知道其存在的多线程。内核级线程(KLT),也称为内核支持的线程或轻量级进程。它在核心空间中实现。内核为每个线程在核心空间设置一个线程控制块,用于注册线程的线程标识符、值、状态、优先级等信息。对线程的所有操作,如创建、撤销、切换等,都是通过系统函数调用在内核中进行相应的处理完成的。内核维护进程和线程的上下文切换和线程切换。在类系统中,一般通过修改流程的实现来实现,可以使用不完整的流程创建。同理创建共享数据空间的过程,这个系统调用在Linux下是clone(),在FreeBSD下是rfork()。5.常见误区5.1CPU占用率高就是CPU资源不足。当CPU计数器超出范围时,不一定是CPU资源不足,其他资源也可能导致。比如当内存不足时,CPU就会忙于内存管理。从表面上看,可能是CPU使用率100%