设为首页 加入收藏

TOP

聊聊Linux中CPU上下文切换(二)
2023-07-23 13:35:18 】 浏览:51
Tags:聊聊 Linux CPU 文切换
,当前进程会被挂起;
  • 发生硬中断,CPU 上的进程会被挂起,然后去执行内核中的中断服务进程。
  • 线程上下文切换

    对操作系统来说,进程是资源分配的基本单位,而线程则是任务调度的基本单位。内核中的任务调度实际是在调度线程,进程只是给线程提供虚拟内存、全局变量等资源。线程上下文切换时,共享相同的虚拟内存和全局变量等资源不需要修改。而线程自己的私有数据,如栈和寄存器等,上下文切换时需要保存。
    关于进程和线程的区别:

    • 当进程中只有一个线程时,可以认为进程就等于线程。
    • 当进程拥有多个线程时,这些线程会共享父进程的资源(即共享相同的虚拟内存和全局变量等资源)。这些资源在上下文切换时是不需要修改的。
    • 另外,线程也有自己的私有数据,比如栈和寄存器等,这些在上下文切换时也是需要保存的。

    因此线程上下文切换有两种情况:

    • 前后两个线程属于不同进程,因为资源不共享,所以切换过程就跟进程上下文切换是一样的;
    • 前后两个线程属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据。

    中断上下文切换

    上下文切换有时也因硬件中断而触发。硬件中断是指硬件设备(如键盘、鼠标、调试解调器、系统时钟)给内核发送的一个信号,该信号表示一个事件(如按键、鼠标移动、从网络连接接收到数据)发生了。
    为了快速响应硬件的事件,中断处理会打断进程的正常调度和执行,然后调用中断处理程序,响应设备事件。在打断其他进程时,需要先将进程当前的状态保存下来,等中断结束后,进程仍然可以恢复回来。

    跟进程上下文不同,中断上下文切换不涉及进程的用户态。所以,即便中断过程打断了一个正处在用户态的进程,也不需要保存和恢复这个进程的虚拟内存、全局变量等用户态资源。中断上下文,只包括内核态中断服务程序执行所必需的状态,也就是 CPU 寄存器、内核堆栈、硬件中断参数等。

    中断上下文切换并不涉及到进程的用户态。所以即便中断过程打断了一个正处在用户态的进程,也不需要保存和恢复这个进程的虚拟内存、全局变量等用户态资源。中断上下文,其实只包括内核态中断服务程序执行所必须的状态,包括 CPU 寄存器、内核堆栈、硬件中断参数等。

    对同一个 CPU 来说,中断处理比进程拥有更高的优先级,所以中断上下文切换不会与进程上下文切换同时发生。并且,由于中断会打断正常进程的调度和执行,所以大部分中断处理程序都短小精悍,以便可以尽快完成。

    上下文切换的消耗

    保存上下文恢复上下文的过程并不是免费的,需要内核在 CPU 上运行才能完成。据测试,每次上下文切换都需要几十纳秒到数微妙的 CPU 时间。特别是在进程上下文切换次数较多的情况下,很容易导致 CPU 将大量时间消耗在寄存器、内核栈、虚拟内存等资源的保存和恢复上,从而大大缩短了真正运行进程的时间。

    Linux相比与其他操作系统(包括其他类 Unix 系统)有很多的优点,其中有一项就是,其上下文切换和模式切换的时间消耗非常少。
    Linux 通过 TLB 来管理虚拟内存到物理内存的映射关系。当虚拟内存更新后,TLB 也需要刷新,内存的访问也会随之变慢。特别是多处理器系统上,缓存是被多个处理器共享的,刷新缓存不仅会影响当前处理器的进程,还会影响共享缓存的其它处理器的进程。所以过多的上下文切换对系统来说意味着会消耗大量的 CPU 时间。

    根据Tsuna的测试报告,每次上下文切换都需要几十纳秒到数微妙的CPU时间,这个时间还是相当可观的。
    不管是哪种场景导致的上下文切换,你都应该知道:

    1. CPU上下文切换,是保证Linux系统正常工作的核心功能,一般情况下不需要开发人员特别关注。
    2. 但过多的上下文切换,会把CPU时间消耗在寄存器、内核栈以及虚拟内存等数据的保存和恢复上,从而缩短进程真正运行的时间,耗费大量的 CPU,甚至严重降低系统的整体性能。

    补充:vmstat命令查看整体CPU上下文切换情况

    上面已经介绍到CPU上下文切换分为进程上下文切换、线程上下文切换、中断上下文切换,那么过多的上下文切换会把CPU的时间消耗在寄存器、内核栈以及虚拟内存等数据的保存和恢复上,缩短进程真正运行的时间,成为系统性能大幅下降的一个因素
    所以我们可以使用vmstat这个工具来查询系统的上下文切换情况,vmstat是一个常用的系统性能分析工具,可以用来分析CPU上下文切换和中断的次数
    执行如下的命令:vmstat 5 (每隔5s输出一组数据)

    该命令输出信息中,各个字段以及含义:
    procs:procs 中有 r 和 b 列,它报告进程统计信息。在上面的输出中,在运行队列(r)中有两个进程在等待 CPU 并有零个休眠进程(b)。通常,它不应该超过处理器(或核心)的数量,如果你发现异常,最好使用 top 命令进一步地排除故障。

    • r:等待运行的进程数。
    • b:休眠状态下的进程数。

    memory: memory 下有报告内存统计的 swpd、free、buff 和 cache 列。你可以用 free -m 命令看到同样的信息。在上面的内存统计中,统计数据以千字节表示,这有点难以理解,最好添加 M 参数来看到以兆字节为单位的统计数据。

    • swpd:使用的虚拟内存量。
    • free:空闲内存量。
    • buff:用作缓冲区的内存量。
    • cache:用作高速缓存的内存量。
    • inact:非活动内存的数量。
    • active:活动内存量。

    swap:swap 有 si 和 so 列,用于报告交换内存统计信息。你可以用 free -m 命令看到相同的信息。

    • si:从磁盘交换的内存量(换入,从 swap 移到实际内存的内存)。
    • so:交换到磁盘的内存量(换出,从实际内存移动到 swap 的内存)。

    I/O:I/O 有 bi 和 bo 列,它以“块读取”和“块写入”的单位来报告每秒磁盘读取和写入的块的统计信息。如果你发现有巨大的 I/O 读写,最好使用 iotop 和 iostat 命令来查看。

    • bi:从块设备接收的块数。
    • bo:发送到块设备的块数。

    system:system 有 in 和 cs 列,它报告每秒的系统操作。

    • in:每秒的系统中断数,包括时钟中断。
    • cs:系统为了处理所以任务而上下文切换的数量。

    CPU:CPU 有 us、sy、id 和 wa 列,报告(所用的) CPU 资源占总 CPU 时间的百分比。如果你发现异常,最好使用 top 和 free 命令。

    • us:处理器在非内核程序消耗的时间。
    • sy:处理器在内核相关任务上消耗的时间。
    • id:处理器的空闲时间。
    • wa:处理器在等待IO操作完成以继续处理任务上的时间。

    补充:pidstat命令查看进程的CPU上下文切换情况

    笔者的环境是:Centos7

    执行如下的命令:pidstat,查看进程的CPU上下文切换情况
    如果没有安装,yum install sysstat安装即可

    在结果中你能看到如下内容:

    • PID - 被监控的任务的进程号
    • %usr - 当在用户层执行(应用程序)时这个任务的cpu使用率,和 nice 优先级无关。注意这个字段计算的cpu时间不包括在虚拟处理器中花去的时间。
    • %system - 这个任务在系统层使用时的cpu使用率。
    • %guest - 任务花费在虚拟机上的cpu使用率(运行在虚拟处理器)。
    • %CPU - 任务总的cpu使用率。在SMP环境(多处理器)中,如果在命令行中输入-I参数的话,cpu使用率会除以你的cpu数量。
    • C
    首页 上一页 1 2 3 下一页 尾页 2/3/3
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇虚拟机磁盘扩容(parted、lvm) 下一篇gitlab拉取指定目录

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目