什么是CPU上下文?
linux是一个多任务系统,可支持远大于CPU个数的任务同时运行。但并非真的同时运行,而是系统在很短的时间内将CPU轮流分配给他们。
在每个任务运行前,CPU要知道任务从哪里加载、从哪里开始运行,也就是说需要系统实现帮它设置好CPU寄存器和程序计数器。
CPU寄存器:是CPU内置的容量小但速度极快的内存。
程序计数器:用来存储CPU正在执行的指令位置或者即将执行的吓一跳指令的位置。
他们是CPU在运行任务前必须依赖的环境,因此被叫做CPU上下文
什么是上下文切换?
上下文切换就是把前一个任务的CPU上下文保存起来,然后加载新任务的上下文到寄存器和程序计数器里,然后再跳转到程序计数器所致的新位置运行新任务。
根据任务不同,CPU上下文切换可分为以下几个不同的场景:
1.进程上下文切换
linux的进程的运行空间氛围内核空间和用户空间。
内核空间(Ring 0)具有最高权限,可直接访问所有资源
用户空间(Ring 3)只能访问受限资源,不能访问内存等硬件设备,必须荣国系统调用内核才能访问这些特权资源
进程在用户空间运行时称为进程的用户态,在内核中运行时称为进程的内核态
从用户态到内核态的转变需通过系统调用来完成
比如:查看文件,需要先调用open()打开文件,再调用read()读取文件,调用write()写入文件最后调用close()关闭文件
2.系统调用会发生CPU上下文切换吗?
系统调用会发生CPU上下文切换。
需先将寄存器里原来的用户态指令位置保存起来,接着为了执行内核态代码,寄存器需要更新为内核态指令的新位置,最后跳转到内核态运行内核任务
系统调用结束后,CPU寄存器需要回复原来保存的用户态,再切换到用户空间,继续执行进程。所以一次系统调用发生了两次CPU上下文切换
系统调用通常称为特权模式切换
3.系统调用和进程上下文切换的区别
(1)进程是由内核来管理调度的,进程切换只发生在内核态。进程的上下文切换不仅包含虚拟内存、栈、全局变量的动用户空间资源还包括了内核堆栈、寄存器等内核空间的状态。所以会比系统调用多一步保存进程上下文的操作,而这个操作可能需要几十纳秒至数微妙的CPU时间,在上下文切换次数较多的情况下,很容易导致CPU将大量时间耗费在寄存器等资源的保存和恢复上,导致平均负载升高。
(2)linux通过TLB(Translation Lookaside Buffer)来管理虚拟内存到物理内存的映射关系,当虚拟内存更新后TLB也要刷新,内存的访问速度随之变慢。特别是多处理器系统上,因为缓存是被多个处理器共享,刷新缓存会影响多个处理器。
4.什么时候会切换上下文?
只要在进程调度的时候才需要切换上下文,linux会将优先级最高和等待CPU时间最长的进程优先运行。
5.进程什么时候会被调度到CPU上运行呢?
(1)当一个正在使用CPU的进程执行完了,这时候系统会在就绪队列里拿一个新的进程来运行。
(2)为了保证所有进程可以公平调度,CPU时间被划分成一段段的时间片,这些时间片被轮流分配给各个进程。当某个进程的时间片耗尽后会被系统挂起,切换到其他正在等待CPU的进程运行。
(3)进程运行需要的资源不足时,进程会被挂起,系统会调度其他进程运行。
(4)进程主动挂起,如调用了sleep将自己挂起。
(5)当有优先级别高的进程运行时,为保证高优先级进程的运行,当前进程会被挂起。
(6)发送硬件终端时,进程会被中断挂起,抓呢执行内核中的中断服务程序。
6.什么是线程
线程与进程最大的区别在于,线程是调度的基本单位,而进程则是资源拥有的基本单位,所以内核调度中的对象是线程而不是进程,进程只是给线程提供了虚拟内存、全局变量等资源。
当进程只有一个线程时,进程=线程
当进程拥有多个线程时,线程共享进程的虚拟内存和全局变量。
线程有自己的私有数据,如栈和寄存器等,这些在上下文切换时需要保存。
线程的上下文切换可以分为以下两种情况
(1)不同进程内的线程切换,因为资源不共享,所以切换过程和进程上下文切换一样。
(2)同进程内线程切换,因为资源共享,所以只需要切换线程的私有数据和寄存器等不共享的数据。
所以说多线程的模式比多进程的模式效率更高
7.什么是中断上下文切换
中断上下文切换拥有比进程更高的优先级。
中断处理会打断进程的正常调度和执行,转而调用中断处理程序,中断你处理程序不会与进程处理同时运行,所以中断程序一般短小精悍。
过多的中断上下文切换会消耗大量CPU和程序的运行效率,所以也是重点排查对象。
怎么查看CPU上下文切换的情况
使用vmstat工具查看
vmstat 是一个常用的系统性能分析工具,主要用来分析系统的内存使用情况,也常用来分析 CPU 上下文切换和中断的次数。
cs:每秒上下文切换的次数
in:每秒中断次数
r:就绪队列长度(正在 运行或等待的CPU进程数)
b:处于不可中断睡眠状态的进程数
使用pidstat工具查看各进程的详细情况
cswch:每秒自愿上下文切换的次数
nvcawch:每秒非自愿上下文切换的次数
自愿上下文切换:指进程无法获取所需自愿导致上下文切换。如I/0、内存等系统自愿不足时,就会发生资源上下文切换。
非自愿上下文切换:指进程由于时间片已到等原因,被系统强制调度而发生的上下文切换。如大量进程争抢CPU时,就容易发生非自愿上下文切换。
案例分析
使用sysbench工具来模拟多线程调度切换情况
sysbench 是一个多线程的基准测试工具,一般用来评估不同系统参数下的数据库负载情况。
先预先安装sysbench和sysstat
sysbench安装:yum install sysbench 验证:sysbench –help
sysstat安装:yum install sysstat 验证:mpstat -V
运行sysbench模拟多线程调度执行语句: