一.简介

Linux是多任务操作系统,cpu划分固定时间片,分给每个进程,当前进程时间片执行完毕,将挂起,运行下一个进程。而进程运行时,需要到寄存器中获得要运行的指令和指令所在内存的位置。

cpu上下文切换,就需要将寄存器中的数据保存到系统内核中,加载新程序的寄存器信息,跳转到计数器所指定的内存位置,开始读取和运行新进程。每次切换需要消耗cpu,繁上下文切换会影响性能。

二.进程切换

Linux 按照特权等级,把进程的运行空间分为内核空间和用户空间。0为内核态,3为用户态

一个进程如果要输出一些信息,只需要在用户空间完成即可,但要读取文件,就需要到内核空间完成,这个转变,就需要系统调用。需要把原先用户态的指令保存,加载内核态的指令到进寄存器,完成指令。这种不会涉及虚拟内存等用户态资源。只是同进程中,为了完成不同权限指令的切换。

进程由内核管理和调度,切换发生在内核态。上下文中保存了虚拟内存,栈,全局变量等用户空间资源,也保存了内核堆栈,寄存器等内核空间资源。因为除了保存寄存器信息,还需要刷新TLB管理的虚拟内存和用户栈

cpu在每个核心上维护了一个就绪列队,将正在运行和等待运行的进程按优先级和等待cpu时间排序。选择优先级最高和等待cpu时间最长的进程运行。

切换理由:

1.cpu划分固定时间片,分给每个进程,当前进程时间片执行完毕,将挂起,运行下一个进程。

2.运行sleep函数,自动挂起。

3.当前进程资源不足,例如内存需要2G,但内存不够,将挂起,当满足后再运行。

4.有优先级更高的进程,则当前进程挂起,运行新进程。

5.硬件中断,进程挂起,执行内核中的中断服务。

三.线程切换

进程是拥有资源的集合体,而线程是执行操作的单位。关系很像公司中部门和人员的关系。每个部分都有不同的资源,而部门中的人员则使用资源完成任务。

当只有一个线程的时候,线程等于进程

当有多个线程的时候,线程共享虚拟内存,全局变量等资源,这些资源上写文切换时不需要更改。

线程有自己的单独数据,栈和寄存器重存储的内容,切换需要保存。

切换理由:

前后2个线程属于不同进程,等同于进程的切换

前后2个线程属于同进程,切换只需要保存私有数据

相比进程的切换,将要节省更多资源

四.中断切换

当有硬件事件,例如在键盘打字,就会中断当前进程,响应硬件设备。中断切换并不涉及进程用户态,不需要保存和恢复虚拟内存,全局变量等用户态资源。只保存内核态,中断服务程序执行所必须的状态,包括cpu寄存器,内核堆栈,硬件终端参数等。

同cpu中,中断优先级最高,所以中断切换和进程之前切换并不会同时发生。

五.中断检测和查看

1.检查上下文切换情况

vmstat

cs(context switch)是每秒上下文切换的次数

in(interrupt)则是每秒中断的次数

r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数

b(Blocked)则是处于不可中断睡眠状态的进程数

2.每个进程的上下文切换情况

pidstat -w 5

cswch(voluntary context switches)每秒自愿上下文切换的次数

是指进程无法获取所需资源,导致的上下文切换,例如I/O、内存等系统资源不足时

nvcswch(non voluntary context switches)每秒非自愿上下文切换的次数

指进程由于时间片已到,有优先级更高的进程启动等原因,被系统强制调度从而切换。当大量进程抢夺cpu时,就容易发生此类切换。

六.模拟

sysbench,多线程基准测试工具

使用sysstat来检查监控和分析,包含mpstat用于查看每颗cpu的状态,pidstat查看每个进程的状态

rpm -ivh https://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm

yum -y install sysbench sysstat

1.查看空闲系统上下文切换数据,3秒一次

vmstat 3

2.单独开一个终端

以 10 个线程运行 5 分钟的基准测试,模拟多线程切换的问题

sysbench --threads=10 --max-time=300 threads run

3.返回第一个终端,可以看到突然变大



r 列:就绪队列的长度已经到了 8,远远超过了系统 CPU,会导致频繁切换

us(user)和 sy(system)列:这两列的 CPU加起来就是100%,sy最高,主要是内核占用

in 列:中断次数也上升到了 1k左右,说明中断处理也是问题

说明等待使用cpu的进程太多,导致大量上下文切换,上下文切换导致cpu占用率升高。

4.查看具体应用

-w 参数表示输出进程切换指标,-u 参数则表示输出 CPU 使用指标

pidstat -w -u 3

可以看到sysbench占用了很高的cpu使用率很高,但没有产生多少上下文切换

5.查看多线程,-t显示线程

pidstat -wt 3

可以看到线程占用的很多

6.查看中断信息

/proc/interrupts 这个只读文件中读取,/proc 实际上是 Linux 的一个虚拟文件系统。/proc/interrupts 就是这种通信机制的一部分,用于内核空间与用户空间之间的通信,提供了一个只读的中断使用情况。

watch -d cat /proc/interrupts

最新文章

  1. APM程序分析-ArduCopter.cpp
  2. 解决表单(搜索框)回车的时候直接提交了表单不运行js的问题
  3. javaweb学习总结—Apache的DBUtils框架学习
  4. 关于view.measure
  5. Codeforces Beta Round #17 A - Noldbach problem 暴力
  6. 基于EventAggregator的事件发布及订阅
  7. 基于Berkeley DB实现的持久化队列
  8. Powershell环境变量
  9. linux LNMP自动安装脚本
  10. Linux RCU机制详解
  11. Annotation基础知识
  12. Educational Codeforces Round37 E - Connected Components?
  13. Debian Security Advisory DSA-4421-1 chromium security update
  14. composer 重装常见错误
  15. PSi-Population Stability Index (PSI)
  16. loadrunner 场景设计-IP Spoofer-多ip负载生成器(Windows平台)
  17. 临时和永久关闭Selinux
  18. ArcGIS案例学习笔记_3_2_CAD数据导入建库
  19. EF架构获取数据时报错:The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. Do you want to correct the value?
  20. nyoj 某种序列

热门文章

  1. [loj3527]地牢游戏
  2. [hdu5901]Count primes
  3. vue属性绑定不能用双括号表达式
  4. C# Pechkin初始化一次后被锁住的问题
  5. NOI2020 同步赛划水记
  6. Codeforces 1511G - Chips on a Board(01trie/倍增)
  7. SPOJ 1557 GSS2 - Can you answer these queries II (线段树+维护历史最值)
  8. Codeforces 626G - Raffles(贪心+堆)
  9. Atcoder Grand Contest 054 题解
  10. P4550 收集邮票 与 灵异的期望