zoukankan      html  css  js  c++  java
  • I/O密集型进程、大量进程的场景以及上下文切换

    一. 上节回顾

    1. 什么是进程?什么是线程?它们之间的区别?

    2. CPU命令

      查看物理CPU的个数

      查看每个物理CPU的核数

      查看逻辑CPU的个数

    3. CPU架构

      从处理器层面查看

      从操作系统层面查看

    4. uptime

      load average:三个负载的含义

      平均负载和CPU使用率

    5. 场景一:CPU密集型进程

    二. 场景二:I/O密集型进程

    1. 在第一个终端里运行

    stress-ng -i 1 --hdd 1 --timeout 600  #hdd表示读写临时文件
    或者stress -i 1 --timeout 600   #iowait没有什么变化,效果不明显
    或者stress -d 1 -t 600      #查看进程时不太明显,进程占用不是很明显

    2. 在第二个终端里运行

    watch -d uptime

    3. 在第三个终端里使用mpstat查看CPU使用率的变化情况

    mpstat -P ALL 5

    在运行的过程中,1分钟的平均负载会慢慢不断升高,其中一个CPU使用率升高超过90%以上,iowait也很高,说明平均负载的升高是由于iowait的升高导致的

    4. 查看是哪个进程导致的

    pidstat -u 5 1

    换stress-ng

    首先得安装stress-ng,yum install -y stress-ng

    三. 场景三:大量进程的场景

    当系统中运行进程超出CPU运行能力时,是不是出现等待CPU的进程情况

    1. 在第一个终端中模拟12个进程

    stress -c 12 --timeout 600

    由于系统只有4个CPU,明显比12个进程要少得多,因此系统CPU处于严重过载状态

    2. 在第二个终端中使用uptime查看

    平均负载高达load average:10.41

    3. 在第三个终端运行pidstat -u 5(一直运行,观察多组数据)来看一下进程的情况

    可以看出,12个进程在抢夺4个CPU,每个进程等待CPU时间(也就是%wait)高达60%以上,明显超出CPU的计算范围,最终导致CPU过载

    总结一下:

    CPU使用率,是单位时间内CPU繁忙情况的统计,跟平均负载并不一定完全对应

    (1) CPU密集型进程:使用大量CPU会导致平均负载升高,此时这两者是一致的

    (2) I/O密集型进程:等待I/O也会导致平均负载升高,但CPU使用率(user%)不一定很高

    (3) 大量等待CPU的进程调度也会导致平均负载升高,此时的CPU使用率也会比较高

    四. CPU上下文切换

    1. 多任务操作系统

    Linux是一个多任务操作系统(一台机器可以多个用户同时登录,另外其他人是无感知的),而Windows是单任务操作系统

    2. CPU上下文

    Linux支持远大于CPU数量的任务同时运行,在每个任务运行前,CPU都需要知道任务从哪里加载,又从哪里开始运行,也就是说,需要系统事先帮它设置好CPU寄存器和程序计数器

    CPU寄存器:是CPU内置的容量小,但速度极快的内存

    程序计数器:是用来存储CPU正在执行的指令位置,或者即将执行的下一个指令位置

    它们都是CPU在运行任何任务前,必须要依赖的环境,因此也被叫做CPU上下文

    3. CPU上下文切换

    先把前一个任务的CPU上下文(CPU寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务

    有人会认为:CPU上下文切换无非就是更新了CPU寄存器的值。这些寄存器,就是为了快速运行任务设计的,为什么影响系统的CPU性能呢?

    操作系统管理的这些任务到底是什么?有人会任务:任务就是进程,任务就是线程。是的,进程和线程是最常见的任务,但除此之外,还有没有其他的任务呢?

    根据任务的不同,CPU上下文切换可以分为几个不同的场景:

    (1) 进程上下文切换

    Linux按照特权等级,把进程的运行空间分为内核空间和用户空间,如下图所示:

    进程既可以在用户空间运行,又可以在内核空间运行,进程在用户空间运行时,被称为进程的用户态,而在内核空间的时候,被称为进程的内核态

    从用户态到内核态的转变,需要通过系统调用来完成,比如:

    在查看文件内容时,需要多次系统调用来完成:首先调用open()打开文件,然后调用read()读取文件内容,并调用write()将内容写到标准输出,最后再调用close()关闭文件

    进程上下文切换是指一个进程切换到另一个进程运行,而系统在调用过程中一直是同一个进程在运行,所以系统调用的过程通常被称为特权切换模式,而不是上下文切换。系统调用是同一个进程、同一个线程的操作,就像打开文件,就是这个动作去执行了,不会又切换到其他的线程来打开文件操作

    (2) 线程上下文切换

    线程与进程的最大区别在于:线程是调度的基本单位,而进程是资源拥有的基本单位,所谓内核中的任务调度实际上调度对象是线程,而进程只是给线程提供了虚拟内存、全局变量等资源

    对于线程和进程,可以这样理解:

    当进程中只有一个线程时,可以认为进程就等于线程

    当进程拥有多个线程时,这些线程会共享相同的虚拟内存和全局变量等资源,这些资源在上下文切换时是不需要修改的

    另外,线程也有自己的私有数据,比如栈和寄存器,这些在上下文切换时也是需要保存的,这样,线程的上下文也可以分为两种情况:

    第一种:前后两个线程属于不同进程,此时,资源不共享,所以切换过程就跟进程上下文切换是一样的

    第二种:前后两个线程属于同一个进程,此时因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保存不动,只需要切换线程的私有数据、寄存器等不共享的数据

    (3) 中断上下文切换

    为了快速响应硬件的事件,中断处理会打断进程的正常调度和执行,转而调用中断处理事件,响应设备事件,而在打断其他进程时,就需要将进程当前状态保存下来,这样在中断结束后,进程仍然可以从原来的状态恢复运行

    中断上下文只包括内核态中断服务程序执行所必须的状态,包括CPU寄存器,内核堆栈,硬件中断参数等

    对同一个CPU来说,中断处理比进程拥有更高的优先级,所以中断上下文切换并不会和进程上下文切换同时发生

    另外,跟进程上下文切换一样,中断上下文切换也需要消耗CPU,切换次数过多也会耗费大量的CPU,严重降低系统的整体性能,所以,在性能测试过程中,当你发现中断次数过多时,需要注意排查它是个给你的系统带来严重的性能问题

    做一个小的总结:

    不管是哪种场景导致的上下文切换,都应该知道:

    CPU上下文切换,是保证Linux系统正常工作的核心功能之一,一般情况下是不需要我们特别关注,但过多的上下文切换,会把CPU时间消耗在寄存器上、内核栈以及虚拟内存等数据的保存和恢复上,从而缩短进程真正运行的时间,导致系统的整体性能大幅下降

    4. 怎么查看系统的上下文切换情况

    vmstat:是一个常用的系统性能分析工具,主要用来分析系统的内存使用情况,也可用来分析CPU上下文切换和中断的次数

    vmstat 5    # 5:每5s更新一次

    procs

    r:表示运行和等待CPU时间片的进程数,这个值如果长期大于系统CPU的个数,说明CPU不足,需要增加CPU

    b:表示在等待资源的进程数,比如正在等待I/O或者内存交换

    ------memory------

    swpd:表示切换到内存交换区的内存大小(单位:KB),通俗讲就是虚拟内存的大小。如果swap的值不为0或者比较大,只要si,so的值长期为0,这个情况一般属于正常的

    free:表示当前空闲的物理内存(单位:KB)

    buff:表示bufferscached内存大小,也就是缓冲大小,一般对块设备的读写才需要缓冲

    cache:表示pagecached的内存大小,也就是缓冲大小,一般作为系统进行缓冲。频繁访问的文件都会被缓存,如果cache值非常大说明缓存文件比较多,如果此时io中的bi比较小,说明文件系统效率比较好

    ------swap------

    si:表示由磁盘调入内存,也就是内存进入内存交换区的内存大小

    so:表示由内存进入磁盘,也就是内存交换区进入内存的内存大小

    一般情况下:si,so的值都为0,如果si,so的值长期不为0,说明系统内存不足,需要增加系统内存

    ------io------

    bi:表示由块设备读入数据的总量,即读磁盘,单位kb/s

    bo:表示写设备数据的总量,就是写磁盘,单位kb/s

    ------system------

    in:表示某一时间间隔内的每秒设备中断数

    cs:表示每次产生的上下文切换次数

    ------cpu------

    us:用户进程消耗的CPU时间百分比,us值越高,说明用户进程消耗CPU时间越多,如果长期大于80%以上,就需要考虑优化程序或者算法

    sy:表示系统内核进程消耗的CPU时间百分比,一般来说us + sy应该小于80%,如果大于80%,说明可能CPU处于瓶颈

    id:表示CPU处于空闲状态的时间百分比

    wa:表示等待CPU的时间百分比,wa值越高,说明I/O等待越严重,根据经验wa的参考值为20%,如果超过20%,说明I/O等待严重,引起I/O等待的原因可能是磁盘大量随机读写造成的,也可能是磁盘的块操作造成的

    st:

    通过上面的描述,如果要来评估CPU,需要重点关注procs的r列值和CPU项的us,sy,wa列的值,system的in,cs的值

     

  • 相关阅读:
    PAT:循环-12. 打印九九口诀表(15) AC
    PAT:循环-07. 爬动的蠕虫(15) 错两个
    PAT:循环-01. 求整数段和(15) AC
    PAT:分支-16. 计算分段函数(10) AC
    PAT:分支-10. 计算个人所得税(10) AC
    PAT:分支-08. 高速公路超速处罚(15) AC
    UIToolBar
    iOS 代码实现获得应用的版本号(Version/Build)
    IOS开发之 ---- iOS8中提示框的使用UIAlertController(UIAlertView和UIActionSheet二合一)
    IOS开发中的CGFloat、CGPoint、CGSize和CGRect
  • 原文地址:https://www.cnblogs.com/my_captain/p/12663865.html
Copyright © 2011-2022 走看看