Intel x86的处理器状态有四个特权级别:0级权限最高,3级权限最低
0级:内核级 处理I/O操作、执行中断处理等关键操作1级:系统调用级 可以执行系统调用,获得特定的和受保护的程序的服务2级:共享库级 可被多个运行进程共享,允许调用库函数,读取但不修改相关数据3级:应用程序级 所受到的保护最少导致处理器从用户态向内核态转换的时机
程序请求操作系统服务,执行系统调用程序运行时,产生中断,转向中断处理程序程序运行时,产生异常事件,转向异常处理程序三类情况都通过中断机制发生
中断和异常是从用户态到内核态转换仅有的途径计算机提供一条特权指令称作加载程序状态字(Intel x86为iret指令),用来实现从从内核态转向用户态,控制权交给应用进程用户栈
进程用户空间中开辟的一块区域,用于保存应用程序的子程序(函数)间相互调用的参数、返回值、返回点以及子程序的局部变量核心栈
也叫系统栈或内核栈,是内存中属于操作系统空间的一块区域一方面,用于保存中断现场,对于嵌套中断,被中断程序的现场信息依次压入核心栈,中断返回时逆序弹出另一方面,保存操作系统程序(函数)间相互调用的参数、返回值、返回点以及程序局部变量每个进程被创建时捆绑一个核心栈,具有可读可写不可执行属性现代操作系统是由“中断驱动”的
中断是指程序执行过程中,遇到急需处理的事件时,暂时中止CPU上现行程序的运行,转去执行相应的事件处理程序,待处理完成后再返回原程序被中断处或调度其他程序执行的过程
在中断事件发生后,中断装置能改变处理器内操作的执行顺序
外中断(中断或异步中断):指来自处理器之外的中断信号
外中断又分可屏蔽中断和不可屏蔽中断每个不同中断具有不同的中断优先级,表示事件的紧急程度,在处理高一级中断时,往往会屏蔽部分或全部低级中断内中断(异常或同步中断):指来自处理器内部,通常由于程序执行中,发现与当前指令关联的、不正常的、或是错误的事件,内中断不可屏蔽
访管中断:由执行系统调用而引起硬件故障中断:如电源失效、协处理器错误、奇偶校验错误、总线超时等程序性异常:如非法操作、地址越界、页面故障、调试指令、除数为0和浮点溢出等中断VS异常:
中断是由与现行指令无关的中断信号触发的(异步的),且中断的发生与CPU处在用户模式或内核模式无关,在两条机器指令之间才可响应中断,一般来说,中断处理程序提供的服务不是为当前进程所需的异常由CPU控制单元产生的,源于现行程序执行指令过程中检测到例外异常与CPU是同步的,允许指令在执行期间响应异常大部分异常发生在用户态,而内核态唯一发生的异常是“缺页异常”异常包括很多方面,有出错(fault),也有陷入(trap)等“中断”要求被快速处理,以便及时响应其它中断信号,所以,中断处理程序处理过程中是不能阻塞的; “异常”处于被打断的当前进程上下文中,所提供的服务是当前进程所需要的,所以,异常处理程序处理过程中是可以阻塞的 中断允许发生嵌套,但异常大多为一重; 异常处理过程中可能会产生中断,但中断处理过程中决不会被异常打断
硬件故障中断
需要人工干预,如复位、设置或替换。中断处理程序保护现场、停止设备工作,停止CPU运行、向操作员报告故障信息。程序性中断
语法错误、逻辑错误、异常 。不同用户处理要求不同,借助于信号机制将捕获中断事件,并原封不动地转交给应用程序自行处理 。I/O中断
I/O操作正常结束 把等待传输的下一个进程设置为就绪态,让它占有设备或通道并启动数据传输。I/O操作发生故障 先向设备发命令索取状态字,分析产生故障的确切原因,再进行复执或请求。人工干预I/O操作发生异常 分析情况采取相应措施,向操作员报告,如通知操作员换卷、装纸等。设备报到或设备结束 表示有设备接入可供使用或设备断开暂停使用,操作系统应修改系统数据结构中相应设备的状态 。访管中断
由程序执行访管指令(包括操作码和访管参数 )引起,可看做机器指令的一种扩充 。机器在执行访管指令时,将访管参数作为中断字并入PSW,同时送入内存中指定单元,操作系统的访管中断处理程序分析访管参数、进行合法性检查后,按照访管参数具体要求进行相应处理 。时钟中断
时钟是操作系统进行调度工作的重要工具利用定时器能够确保操作系统在必要时获得控制权,陷入死循环的进程最终会因时间片耗尽而被迫让出处理器时钟可分成绝对时钟和间隔时钟两种,通常使用一个硬件时钟,按照固定周期发出中断请求 绝对时钟寄存器:定时地把此寄存器的内容加1 间隔时钟寄存器:通过程序设置此寄存器初值,在每个时间切换点将的内容减1,内容为0时产生间隔时钟中断Linux系统运行不同的间隔定时器,类型有三种
real:间隔定时器按实际经过时间计时,不管进程处在何种模式下运行,包括进程被挂起时,计时总在进行,定时到达时发送给进程一个SIGALRM信号virtual:间隔定时器进程在用户态下执行时才计时,定时到达时发送给进程一个SIGVTALRM信号profile:间隔定时器进程执行在用户态或核心态时都计时,当定时到达时发送给进程一个SIGROF信号Linux系统允许进程同时启动多个定时器,定时器工作所需时间值及有关信息保存在进程的task-struct中
CPU可以通过指令设置可编程中断控制器的屏蔽码 中断屏蔽是指禁止CPU响应中断或禁止中断产生
禁止CPU响应中断指硬件产生中断请求后,CPU暂时不予响应的状态,等待直到中断开放后,被屏蔽的中断才能被响应并获得处理。常常用在处理某个中断时,防止同级或高级中断干扰,或内核处理临界区时,必须连续执行防止被意外事件打断禁止中断产生指可引起中断的事件发生时,硬件不允许提出中断请求,也不通知处理器,故不可能导致中断。由于中断被禁止而不可能导致中断,通常设备中断、时钟中断等可以被暂时禁止负责对硬件做出迅速响应,并完成时间要求很严格的操作
异步方式执行,可能会打断其他重要代码的执行中断处理程序执行过程中 最好情形下,同级中断被屏蔽 最坏情形下,当前处理器上所有其他中断都会被屏蔽中断处理程序不在进程上下文中运行,不能被阻塞上半部:中断处理程序
简单快速,执行时禁止部分或全部中断下半部:
执行与中断处理密切相关但中断处理程序本身不执行的工作执行期间可以响应中断没有严格的划分规则
如果任务对时间非常敏感,放在中断处理程序中执行如果任务与硬件相关,放在中断处理程序中执行如果任务需确保不被其他中断(同级中断)打断,放在中断处理程序中执行其他任务,考虑放置在下半不执行软中断 tasklet 工作队列
tasklet实现在软中断之上;tasklet和软中断也称为可延迟函数
一组静态定义的下半部接口
有32个,必须在编译阶段静态注册可以在所有处理器上同时执行(即使两个类型相同的软中断)一个软中断不会抢占另一个软中断软中断处理过程中允许响应中断,但自己不能休眠在一个处理程序运行的时候,当前处理器上的软中断被禁止软中断预留给系统中对时间要求最严格以及最重要的下半部使用 适用于执行频率很高且连续性要求很高的情况
基于软中断实现、灵活性强、动态创建
类型相同的tasklet不能同时执行两种不同类型的tasklet可以在不同处理器上同时执行tasklet由HI_SOFTIRQ及TASKLET_SOFTIRQ两类软中断代表组成,前者的优先级高于后者tasklet与软中断的权衡
通常应该使用tasklet软中断适用于执行频率很高且连续性要求很高的情况tasklet调度:激活相应软中断的挂起状态
基于软中断实现、灵活性强、动态创建
将工作推后,交由一个内核线程去执行
下半部分在进程上下文执行,通过工作队列执行的代码可以占尽进程上下文的所有优势(支持使用大容量内存, 支持获取信号量, 支持执行阻塞式I/O操作)工作队列可以用内核线程替换,但一般不建议单独建立对应的内核线程工作队列vs.软中断/tasklet
工作队列支持睡眠,软中断/tasklet不支持若需要使用一个可以重新调度的实体来执行下半部分处理,则应该使用工作队列“可再用” 程序
在被调用过程中可以有自身修改,调用程序退出前不允许其他程序来调用“可再入”
能够被多个程序同时调用的程序是纯代码,在执行过程中不被修改调用它的各应用程序提供工作区定义:
进程是可并发执行的程序在某个数据集合上的一次计算活动,也是操作系统进行资源分配和保护的基本单位进程性质
原理角度:是支持程序执行的一种系统机制,它对处理器上运行程序的活动规律进行抽象实现角度:是一种数据结构,用来准确地刻画运行程序的状态和系统动态变化状况分析
进程是一个既能用来共享资源,又能描述程序并发执行过程的系统基本单位引入进程的代价:进程占用的空间、调度进程的时间代价
属性:
动态性 一次执行过程、有生命周期、创建/调度/等待共享性 同一程序同时运行于不同数据集合上时,构成不同进程 进程和程序不是一一对应的独立性 独立实体,有自己的虚存空间、程序计数器和内部状态制约性 共享资源或协同工作,产生相互制约关系,必须对进程的执行次序,或相对执行速度加以协调并发性 多个进程的执行在时间上可以重叠 在多处理器环境中可并行执行
挂起状态引入原因
为了让某些进程暂时不参与低级调度,释放它占有的资源,以平滑系统负荷进程挂起的原因多种多样,如
内存资源已经不能满足进程运行的要求,此时必须把某些进程挂起(suspend),对换到磁盘对换区中可能系统出现故障,需要暂时挂起一些进程,以便故障消除后,再解除挂起并恢复进程运行用户调试程序过程中,可以请求挂起他的进程,以便进行某种检查和修改进程不能立即被执行
挂起进程可能会等待事件,但所等待事件是独立于挂起条件的,事件结束并不能导致进程具备执行条件进程进入挂起状态是由于操作系统、父进程或进程本身阻止它的运行结束进程挂起状态的命令只能通过操作系统或父进程发出进程映象定义
某时刻进程的内容及其状态集合进程映象组成
进程控制块 每个进程捆绑一个,用来存储进程的标志信息、现场信息和控制信息进程程序块 被进程执行的程序,规定进程一次运行所应完成的功能进程核心栈 每个进程捆绑一个,进程在内核态工作时使用,用来保存中断/异常现场,保存函数调用的参数、局部变量和返回地址等进程数据块 进程的私有地址空间,存放各种私有数据,用户栈也在数据块中开辟,用于在函数调用时存放栈帧、局部变量和返回地址等参数进程上下文:
进程上下文是进程物理实体和支持进程运行的环境进程上下文组成:
用户级上下文 由程序块(可执行的机器指令序列)、数据块(进程可访问的信息)、共享内存区(进程通信使用的内存区)、用户栈(存放函数调用过程中的信息)组成,占用进程的虚存空间系统级上下文 由进程控制块(进程的状态)、内存管理信息(进程页表或段表)、核心栈(进程内核态运行时的工作区)等操作系统管理进程所需要的信息组成寄存器上下文 由处理器状态寄存器(进程当前状态)、指令计数器(下一条该执行的指令地址)、栈指针(指向用户栈或核心栈当前地址)、通用寄存器等组成 当进程不处于运行态时,处理器状态信息保存在寄存器上下文中也称为进程描述符(process descriptor)
进程存在的唯一标识操作系统用来记录和刻画进程状态及环境信息的数据结构,是进程动态特征的汇集操作系统掌握进程的唯一资料结构和管理进程的主要依据进程控制块包含三类信息
标识信息 包括用户外部标识符(用户/用户组标识ID)和系统内部标识号(进程/进程组标识ID )现场信息控制信息 用于管理和调度进程,包括进程调度相关信息、进程组成信息、进程族系信息、进程间通信信息、进程段/页表、进程映像在外存中的地址、CPU的占用和使用信息、进程特权信息 、资源清单进程队列:处于同一状态的所有PCB链接在一起的数据结构
队列排队规则
可按先来先到、优先数或其它原则排队通用队列组织方式
链接方式 单向链接的每个PCB的链接指针向下一个进程PCB的地址或在PCB表中的编号,编号为0表示队尾 双向链接的每个PCB的前向链接指针指向上一个进程的PCB的地址或在PCB表中的编号,编号为0表示排在队首;向随其后的下一个进程的PCB的地址或在PCB表中的编号,编号为0表示排在队尾索引方式进程上下文切换:
进程切换是让处于运行态的进程中断运行,让出处理器,这时要做一次进程上下文切换程切换发生位置:在内核态而非用户态发生处理器的状态切换(用户态-内核态)不一定引起进程上下文切换
由操作系统中的原语实现:
在管态下执行执行过程中不允许被中断执行是顺序的而不可能是并发的当一个进程创建另一个进程时,生成进程称为父进程,被生成进程称为子进程,父进程可以创建多个子进程,从而形成树状族系关系
进程创建过程:
在进程列表中增加一项,从PCB池中申请一个空闲PCB,为新进程分配惟一的进程标识符为新进程的进程映像分配地址空间,以便容纳进程实体:进程管理程序确定加载到进程地址空间中的程序为新进程分配除主存空间外的其他各种所需资源初始化PCB,如进程标识符、处理器初始状态、进程优先级等把新进程状态置为就绪态,并移入就绪进程队列通知操作系统的某些模块,如记账程序、性能监控程序fork( ):父子进程是独立的进程 clone( ) :父子进程允许共享资源 vfork( ):子进程租用父进程地址空间
进程完成特定工作或出现严重错误后,必须被撤销,进程撤销可分为:正常撤销和非正常撤销
进程撤销过程:
根据撤销进程标识号,从相应队列中找到并移出它将该进程拥有的资源归还给父进程或操作系统若该进程拥有子进程,先撤销所有子进程,以防它们脱离控制回收PCB,并归还到PCB池进程阻塞步骤:
停止进程执行,保存现场信息到PCB修改进程PCB有关内容(如进程状态由运行态改为等待态等),并把修改状态后的进程移入相应事件的等待队列中转入进程调度程序去调度其他进程运行进程唤醒步骤:
从相应的等待队列中移出进程修改进程PCB的有关信息(如进程状态改为就绪态),并移入就绪队列若被唤醒进程比当前运行进程优先级高,重新设置调度标志解决思路:把进程的两项功能:“独立分配资源”与“被调度分派执行”分离开来
进程作为系统资源分配和保护的独立单位,不需要频繁地切换线程作为系统调度和分派的基本单位,能轻装运行,会被频繁地调度和切换进程是操作系统中除处理器外进行的资源分配和保护的基本单位
它有独立的虚拟地址空间,容纳进程映像(如与进程关联的程序与数据),并以进程为单位对各种资源实施保护,如受保护地访问处理器、文件、外部设备等线程是操作系统进程中能够独立执行的实体(控制流),是处理器调度和分派的基本单位
线程是进程的组成部分,每个进程内允许包含多个并发执行的实体(控制流),这就是多线程进程vs.线程
线程又称轻量进程线程运行在进程的上下文中,并使用进程的资源和环境系统调度的基本单位是线程而不是进程,每当创建一个进程时,至少要同时为该进程创建一个线程线程状态:运行、就绪、等待和终止 由于线程不是资源拥有单位,挂起状态对线程是没有意义
调度员/工作者模式 进程中的一个线程担任调度员,接收和处理工作请求,其他线程是工作者线程,由调度员线程分配任务并唤醒工作者线程
组模式 各个线程都可以取得并处理工作请求,有时每个线程被设计成专门执行特定任务,并建立相应任务队列
流水线模式 线程排成某个次序,第一个线程所产生的数据传送给下一个线程进行处理,依次类推,数据按照排定次序由线程依次传递以完成被请求的任务
多线程技术的应用
内核级线程KLT(如OS/2) 内核级线程指线程管理工作由内核完成,并提供线程API来使用线程
用户级线程ULT(如Java ,Informix) 用户级线程指线程的管理工作由应用程序来做,在用户空间内实现,内核不知道线程的存在 线程库是一个ULT管理的例行程序包,主要功能有:线程创建、调度、管理等
混合式线程(如Solaris) 实现分为两个层次:用户层和核心层 用户层线程在用户线程库中实现,核心层线程在内核中实现 在混合式线程系统中,内核必须支持内核级多线程的建立、调度和管理,同时也允许应用程序建立、调度和管理用户级线程
优点
在多处理器上核能够同时调度同一进程中的多线程并行执行若进程中的一个线程被阻塞 ,内核能够调度同一进程的其他线程占有处理器运行,也可以运行其他进程中的线程由于内核级线程只有很小的数据结构和堆栈,切换速度快,内核自身也可用多线程技术实现,从而,提高系统的执行效率缺点
线程在用户态运行,而线程的调度和管理在内核实现,在同一进程中,控制权从一个线程传送到另一个线程时需要用户态-内核态-用户态模式切换,系统开销较大优点
线程切换无须使用内核特权方式,所有线程管理的数据结构均在用户空间中,可以节省模式切换开销和内核的宝贵资源允许进程按照应用的特定需要选择调度算法,且线程库的线程调度算法与操作系统的低级调度算法无关能够运行在任何操作系统上,内核无须做任何改变缺点
由于大多数系统调用是阻塞型的,因此,一个用户级线程的阻塞将引起整个进程阻塞用户级线程不能利用多重处理的优点,进程由内核分配到CPU上,仅有一个用户级线程可以执行,因此不可能得益于多线程的并发执行操作系统调度程序需要根据是用户级线程还是内核级线程来决定对进程和线程的调度方法
用户级线程的调度 由于内核并不知道有线程存在,所以,操作系统调度程序还是以进程为单位进行调度内核级线程的调度 操作系统调度程序会选择一个优先级高的线程运行,不用考虑该线程属于哪个进程现代UNIX内核:引入三种机制优化进程创建效率
写时复制技术(Copy-On-Writing)轻量级进程 允许父子进程共享页表、打开文件列表、信号处理等数据结构 但每个进程应该有自己的程序计数器、寄存器集合、核心栈和用户栈vfork() 新进程可共享父进程的内存地址空间参考另一位博主的阐述:
fork()函数调用之后子进程从fork()语句之后开始执行,其原因是子进程复制了程序计数器在刚刚fork之后父子进程之间的数据段(全局变量),栈段(局部变量),堆段(动态内存),代码段,程序计数器等都是相同的(在当前的linux版本中遵从的是读时共享写时复制的原则)父子之间不同的是进程ID,fork函数的返回值共享的是文件描述符以及mmap建立的映射区 ———————————————— 版权声明:本文为博主「JoshuaCL」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_27357649/article/details/90939370vfork()创建的子进程与父进程共享地址空间
子进程作为父进程的一个单独线程在其地址空间运行子进程从父进程继承控制终端、信号标志位、可访问的主存区、环境变量和其他资源分配子进程对虚拟空间任何数据的修改都可为父进程所见父进程将被阻塞,直到子进程调用execve()或exit()与fork()的关系
功能相同,但vfork()但不拷贝父进程的页表项子进程只执行exec()时,vfork()为首选参考另一位博主关于fork()与vfork()的详细解释: 可以看出使用vfork时,系统调用会等待子进程开始执行后返回,其实这样操作的原因也是因为子进程没有自己的页表项,如果不做等待的操作,会导致主进程和子进程使用同样页表,两个进程用样的页表,想想后果吧。 所以可以看出vfork和fork本质上的区别是:fork的子进程会拷贝主进程的页表项,而vfork的子进程共享主进程的页表项。
因为这样的区别,所以使用vfork时主进程会等待子进程执行exec或exit操作后才会开始执行;如果vfork的子进程中不包含exec或者exit操作,而是直接退出,则会有导致主进程的操作异常,因为主进程的页表项在子进程退出的时候已经销毁,相当于主进程自己没了页表项。 那么vfork的好处是什么呢?避免一次主进程页表项的拷贝,因为子进程一般都会调用exec执行自己的程序代码,而在exec过程中会创建自己的页表项,根本不需要复制主进程的页表项。 那么vfork在现代Linux中是否真能体现它的优点呢?其实不尽然。 在拷贝页表项时,调用了函数dup_mm,其中会使用到COW(写时复制)技术(dup_mm-->copy_page_range),所谓的内存拷贝其实只是对内存的一个标记,只有在需要对该区域进行标记而已,并不会真正的拷贝。———————————————— 版权声明:本文为博主「江明大吴」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/wu330/article/details/49127835
另一篇博主关于fork、vfork、clone的介绍blog
也称为守护进程,独立运行在内核空间的标准进程,支持内核在后台执行一些操作
刷新磁盘高速缓存交换出不用的页框维护网络链接等待与普通进程的区别:
只运行在内核态,内核线程没有独立的地址空间(mm指针被设置为NULL)每个内核线程执行一个单独的内核函数只使用大于PAGE_OFFSET的线性地址空间mm
指向虚存地址空间的用户空间部分内核线程不能访问用户空间,mm为NULLactive_mm:主要用于优化
由于内核线程之前可能是任何用户层进程在执行,内核线程不能修改其内容,故将mm设置为NULL如果切换出的是用户进程,内核将原来进程mm存放在新内核线程的active_mm中如果内核线程之后运行的进程与之前是同一个,内核并不需要修改用户空间地址表,TLB中的信息仍然有效如果内核线程之后运行的进程与之前不是同一个,才需要切换,并清除对应的TLB数据根据内存资源情况决定内存中所能容纳的进程数目,并完成外存和内存中的进程对换工作
根据某种原则决定就绪队列中的哪个进程/线程获得处理器,并将处理器出让给它使用
剥夺式(preemptive) ,又称抢先式
高优先级进程/线程可剥夺低优先级进程/线程当运行进程/线程时间片用完后被剥夺非剥夺式(nonpreemptive),又称非抢先式
一旦某个进程/线程开始运行后便不再让出处理器,除非进程/线程运行结束主动放弃处理器因发生某个事件而不能继续执行剥夺式vs.非剥夺式
剥夺式策略比非剥夺式策略开销要大,主要是调度程序自身开销,及内存和磁盘对换程序及数据的开销剥夺式策略可以避免进程/线程长时间地独占处理器,对于实时系统和分时系统有利,能为用户提供高性能服务把SJF算法改为抢占式的:
如果新作业需要的CPU时间比当前正在执行的作业剩余下来还需的CPU时间短,SRTF强行赶走当前正在执行作业FCFS与SJF是片面的调度算法
FCFS只考虑作业等候时间而忽视了作业的计算时问SJF只考虑用户估计的作业计算时间而忽视了作业等待时间HRRF是介乎这两者之间的折衷的非剥夺式算法
选择响应比最高者投入运行 既考虑作业等待时间,又考虑作业的运行时间 既照顾短作业又不使长作业的等待时间过长响应比定义 响应比 =1+已等待时间/估计运行时间 短作业容易得到较高响应比 长作业等待时间足够长后,也将获得足够高的响应比 饥饿现象不会发生HRRF 算法缺点 计算响应比导致一定时间开销,其性能比 SJF 算法略差静态优先数法
使用外围设备频繁者优先数大,这样有利于提高效率重要算题程序的进程优先数大,这样有利于用户进入计算机时间长的进程优先数大,这样有利于缩短作业完成的时间交互式用户的进程优先数大,这样有利于终端用户的响应时间等等动态优先数法
根据进程占有CPU时间多少来决定: 当进程占有CPU时间愈长,被阻塞后再次获得调度的优先级就越低根据进程等待CPU时间多少来决定: 当进程在就绪队列中等待时间愈长,被阻塞之后再次获得调度的优先级就越高时间片调度
调度程序每次把CPU分配给就绪队列首进程使用一个时间片,就绪队列中的每个进程轮流地运行一个时间片当这个时间片结束时,强迫一个进程让出处理器,让它排列到就绪队列的尾部,等候下一轮调度轮转策略可防止那些很少使用外围设备的进程过长的占用处理器而使得要使用外围设备的那些进程没有机会去启动外围设备
轮转策略与间隔时钟 :时间片的设定
又称反馈循环队列或多队列策略
将就绪进程分为两级或多级,系统相应建立两个或多个就绪进程队列,较高优先级的队列一般分配给较短时间片处理器调度先从高级就绪进程队列中选取可占有处理器的进程,只有在选不到时,才从较低级的就绪进程队列中选取调度方法
基于分时技术的抢占式调度 CPU时间被划分成“时间片”,为每个可运行进程分配一个时间片 分时依赖于时钟中断,对进程透明调度策略
进程分类 普通进程 实时进程优先级 静态优先级 动态优先级有静态优先级、动态优先级、实时优先级
Linux 2.6负载均衡的“拉”操作基本思想
当某个 CPU负载过轻、而另一 CPU负载较重时,系统会从重载 CPU上“拉”进程过来“拉”的负载平衡操作实现在 load_balance() 函数中,有两种调用方式“忙平衡”:当前 CPU不空闲“空闲平衡”:当前 CPU空闲“拉”进程的具体动作在pull_task()函数中实现