【Linux】进程概念

⭐博客主页:️CS semi主页
⭐欢迎关注:点赞收藏+留言
⭐系列专栏:Linux
⭐代码仓库:Linux
家人们更新不易,你们的点赞和关注对我而言十分重要,友友们麻烦多多点赞+关注,你们的支持是我创作最大的动力,欢迎友友们私信提问,家人们不要忘记点赞收藏+关注哦!!!

【Linux】进程概念


一、了解冯诺依曼体系

1、概念

在这里插入图片描述
存储器指的是内存,有只读存储器和随机访问存储器。在不考虑缓存的情况下,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备),外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。

2、数据流向

数据在硬件层面进行流向的时候,所有的输入单元的数据必须先写到存储器中 ,CPU通过某种方式访问存储器,将数据读到CPU的内部,控制器控制着运算器进行操作运算,再通过控制器控制着数据进行流向内存再经过输出设备流出。

3、利用冯诺依曼体系控制文件数据的流入流出

在这里插入图片描述

4、CPU结构

在这里插入图片描述

思考一个问题:为什么数据先存入内存而不是直接通过磁盘与CPU进行交互?
我们可以了解到CPU的运算是纳米级别的,内存是微秒级别的,磁盘是毫秒级别的,一款计算机的好坏不取决于其最慢的那个,我们称之为“木桶效应”。也就是说,如果我们的磁盘和CPU直接进行接收数据并进行运算和控制的操作的时候,效率取决于磁盘的速度,很慢,所以中间搭了一个桥(内存),通过内存与CPU的交互速率取决于内存的速度,较为快速,但有些人问为什么不用寄存器?原因是因为寄存器是在是太贵了,容量也小。

在这里插入图片描述

二、操作系统(OS)概念

1、概念

任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。
操作系统的包含:
内核(进程管理,内存管理,文件管理,驱动管理)
其他程序(例如函数库,shell程序等等)

2、为什么要有操作系统?

与硬件交互,管理所有的软硬件资源为用户程序(应用程序)提供一个良好的执行环境。在整个计算机软硬件架构中,操作系统的定位是:一款纯正的“搞管理”的软件。

换而言之,操作系统是:
对上层:(目的)给用户提供稳定、安全和稳定的运行环境。
对下层:(方式)管理好软硬件资源。

3、管理概念和结构

在我们讲计算机内部的管理概念前,我们用我们再熟悉不过的学校里面校长、辅导员、学生的概念让大家进行更好地理解:

管理者和被管理者不需要认识(你见过校长吗?校长见过底下每一个学生吗?)
学生 (被管理者) —— 软硬件
辅导员 (执行者) —— 驱动
校长 (管理者) —— 操作系统

校长是怎么管理学生的?校长对我们学生做出决策,校长并不认识我们每个人,但他通过辅导员这个中介可以进行将我们进行管理。

***管理者身份管理:
1、用结构体来描述一个学生的数据
2、用特定的数据结构来组织,对学生的管理工作,变成了对数据结构的增删查改———对多个学生进行管理。

在这里插入图片描述

管理的概念:先描述,再组织。
先描述:被管理的对象
再组织:将被管理的对象用特定的数据结构组织起来

也就是我们在进行管理的时候,是先将我们的被管理对象的各个信息先描述出来,再将各个学生的结构体通过数据结构的相关知识进行组织并链接,对学生的管理工作变成了对数据结构的增删改查。

对应到操作系统:
在这里插入图片描述

4、系统调用和库函数概念

在开发角度,操作系统对外会表现为一个整体,它不相信任何用户,但是会暴露自己的部分接口,供上层开发者使用,这部分由操作系统提供的接口,叫做系统调用。
系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者就对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。

类比:老大爷(用户)到银行(操作系统)取钱的时候,因为他不会怎么取钱,所以就叫来了前台(调用库)来进行指导操作,而这个库函数是system call系统调用接口供老大爷更好地取钱。

三、进程

1、基本概念

课本概念:程序的一个执行实例,正在执行的程序等。
内核观点:担当分配系统资源(CPU时间,内存)的实体。

在这里插入图片描述
解析:代码角度为当我们写完一个代码以后进行编译链接后便会生成一个可执行程序,这个可执行程序严格来讲为文件,放在磁盘上的,当我们双击打开这个可执行程序的时候,将其运行起来的时候,本质来讲也就是将这个可执行进程加载到内存中了,CPU才能对其程序进行逐语句的执行,而当这个程序加载到内存了以后,我们称之为进程。 windows桌面app角度,当我们双击桌面的app的时候,本质上是启动了一个进程。 linux层面角度,当我们输入指令./xxx的时候也就是开启了一个进程。

在这里插入图片描述

2、描述进程----PCB

六字真言:先描述,再组织!

当我们刚刚开机的时候启动的第一个程序就是我们的操作系统,而操作系统是做管理工作的,经过先描述再组织的六字真言,当一个进程出现的时候,操作系统立马对它进行描述,再将其组织,通过的是双链表的形式组织起来。

进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。课本上称之为PCB(process control block),Linux操作系统下的PCB是: task_struct。

我们通过一张图来形容一下什么是进程的先描述再组织:
在这里插入图片描述
通过在磁盘中写的代码为test.c,然后进行编译链接后为test.exe可执行程序,再将其拷贝一份进入到OS操作系统中,而操作系统对每一个进程都进行描述,形成了一个个的进程控制块(PCB),然后再通过双链表将其链接组织起来,所以,此后操作系统仅仅需要拿到这个双链表的头结点,便可以访问到所有的PCB进程,而我们仅仅需要对双链表的增删改查即可管理整个进程。

举个例子,我们写了一个程序为mytest.c,经过编译链接后,变成mytest.exe,它仅需进入到PCB的队列中即可,这样我们根据优先级去将它们进行获取信息和执行信息。
在这里插入图片描述

3、什么是进程?

讲了那么多概念和PCB,那什么是进程呢?

进程 = 对应的代码和数据 + 进程对应的PCB结构体

struct PCB
{
	// 进程的全部属性信息
};

在Linux中描述进程的结构体叫做task_struct。task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。

struct task_struct
{
	// 进程的全部属性信息
};

task_ struct内容分类
标示符: 描述本进程的唯一标示符,用来区别其他进程。
状态: 任务状态,退出代码,退出信号等。
优先级: 相对于其他进程的优先级。
程序计数器: 程序中即将被执行的下一条指令的地址。
内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
其他信息

4、查看进程

在根目录中有一个proc进程文件!
在这里插入图片描述

我们通过ls /proc/指令看一下有啥:
进程启动后,会在/proc下形成目录,以自身PID的编号作为目录文件名
在这里插入图片描述
我好奇地想看一下编号为1的那个进程是个啥:
在这里插入图片描述
每个进程都会有一个属性,来保存自己所在的工作路径

通过ps/top+grep命令查看进程信息

先写入一个代码:
在这里插入图片描述

5、通过系统调用获取进程的PID和PPID

当前进程:PID ---- getpid()
父进程:PPID ---- getppid()

通过代码来测试:
在这里插入图片描述

ps axj | head -1 && ps axj | grep proc | grep -v grep
在这里插入图片描述

当这段代码生成可执行程序后,就可以循环打印该进程的PID和PPID了,我们再通过ps命令得到进程的PID和PPID,发现系统调用的PID和PPID与运行后查出的信息的PID和PPID所获取的值相同。

-bash

我们根据上面的进程发现PPID是13462,我们看一下13462是个啥?
在这里插入图片描述
父进程是个bash!
我们在操作命令行的时候,父进程永远是bash外壳,其原理:shell外壳通过创建子进程的方式,以bash的子进程去执行
我们将bash理解成王婆,她现在不自卖自夸,做起了管理,招了实习生(子进程),也就是说,当我们登录成功后,王婆会一直跟着我们,当我们输入命令行的时候,王婆就会帮我们创建一个子进程去执行。

6、批量注释&取消注释

批量注释:Ctrl + v 进入块选择模式,然后移动光标选中你要注释的行,再按大写的I进入行首插入模式输入注释符号如 // 或 #,输入完毕之后,按两下ESC,Vim会自动将你选中的所有行首都加上注释,保存退出完成注释。

取消注释:Ctrl + v 进入块选择模式,选中你要删除的行首的注释符号,注意// 要选中两个,选好之后按d即可删除注释,ESC保存退出。

四、通过系统调用创建进程-fork初识

创建子进程:
在这里插入图片描述
在这里插入图片描述
我们调用fork函数怎么打印了两次?我们深入探讨:

1、如何理解fork创建子进程?

fork本质是创建进程,也就是系统中多了一个进程,也就是多了一份与进程相关的PCB+代码和数据,我们的fork创建了一个子进程,也就是仅有PCB,而该子进程的代码和数据呢?

在这里插入图片描述

默认情况下,子进程会继承父进程的代码和数据
💖代码:父子进程代码共享,但是父子进程对应的id值不同,所以会执行不同的代码
💖数据:默认情况下,数据也是“共享的”,不过修改时会发生写时拷贝来维护数据的独立性。
子进程内核的数据结构task_struct,也会以父进程的为模板初始化自身
注意:父子进程的数据各自开空间(写实拷贝)

我们通过一个代码来看一下 PID和PPID:
在这里插入图片描述

延伸出一个问题:既然有两个打印结果,代码是从上往下运行的,是不是走if完了以后再走else if?
在这里插入图片描述

答案当然是不可能的!if 和else if 不能一起走的,其实是有两个返回值,也就是要走两次代码,也就是各自执行各自的return。

2、fork的两个返回值

(1)怎么理解一个函数有两个返回值?

当我们使用fork函数的时候,子进程就已经被创建了,甚至可以被调度了,父子进程会进行不同的return语句返回。也就是返回两次。

(2)fork后的子进程和父进程proc做着同样的事情吗?

答案当然是不做同一件事情,不然这么设计就很没有意义了!通过我们写的if-else分流,子进程和父进程进行不同的代码段,执行着不同的事情。
创建失败:<0
创建成功:给父进程返回子进程的PID;给子进程返回0,表示成功创建

(3)为什么给父进程返回子进程的PID,而给子进程返回0?

简单理解一个概念,你只有一个爸爸,而爸爸可以有很多孩子!
因为父进程会创建好几个子进程,方便父进程对子进程进行管理(父亲给孩子起名);子进程为0是为了彰显出子进程对父进程是唯一的。

在这里插入图片描述

(4)子进程先运行还是父进程先运行?

不一定!!这个是由操作系统的调度器决定的。

五、进程状态

一个进程从它开始被创建到撤销最后到消亡的整个生命周期,有时候进程需要占用CPU处理器进行跑进程,有时候它处于一个可运行的情况下但在排队不能直接让处理器运行,有时候它处于一个空闲状态……所以进程是不断变化的动态的状态,所以就有了进程状态这一概念。

进程状态的kernel源代码的定义

进程的状态信息也是在task_struct(PCB)中。进程状态的意义在于方便操作系统快速判断进程,并完成特定的功能,比如调度。本质上是一种分类。

/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};

(来自百度)
在这里插入图片描述

ps axj && ps aux

在这里插入图片描述

运行状态-R(running)

当一个进程正处于运行状态的时候,并不意味着进程一定处于运行当中,进程可能在运行队列中等或者正在被执行,就叫做运行态,随时可以被CPU调度。也就是说,可以同时存在多个R状态的进程,所有处于运行状态下的进程,即可被调度的进程,都被放到运行队列当中,当操作系统需要切换进程运行时,直接在运行队列中选取进程运行即可。

在这里插入图片描述

在这里插入图片描述

浅度睡眠-S(sleeping)

该进程正在等待某件事情的完成,处于浅度睡眠状态的进程随时可以被唤醒,也可以被杀掉(可中断睡眠)–kill。

在这里插入图片描述
我们让该进程在前台等50秒看一下进程相关的STAY状态:

ps axj | head -1 && ps axj | grep proc | grep -v grep

在这里插入图片描述

当然,当这个程序结束/ctrl+c,进程退出,结束。
同样,我们也可以用kill命令杀死程序:
在这里插入图片描述

小知识:我们的scanf同样是等待状态,我们画个图来解析一下:
在这里插入图片描述

深度睡眠-D(disk sleep)

也叫不可中断睡眠状态(uninterruptible sleep)
一个进程处于深度睡眠的状态下,表示该进程不会被杀掉,也就是kill -9都没用,只有等该进程自动唤醒才可以恢复。

我们结合图举个例子:
我们熟知,浅度睡眠的进程是处于等待队列中的,也就是一直要放在OS当中的,等待着OS将它放到运行队列然后被CPU调度,可是呢,等待队列中的进程是在是太多了,满了!而这个时候,刚好某一事情做完,有一个浅度睡眠的X进程刚好要被放到磁盘中,可是呢,磁盘的运行速度比OS的运行速度慢的多的很,磁盘把这个进程的copy先放进来,进行加载拷贝,可是此时OS等不住了,看咋有个浅度睡眠的X进程,OS也不知道它在干啥,反正是个浅度睡眠的进程,杀掉就杀掉算了,X进程被杀掉了,过了一会,磁盘加载了失败了,它慢悠悠探出脑袋,看咋X进程咋回事?然后磁盘不明白情况又开始重新加载一次或者是干脆扔掉了(但大概率是重新加载一次),然后无辜的X进程伸冤:我还正在传文件,这么一搞我的进程数据全面丢失,所以最后到底是谁的锅?
OS申辩:我仅仅是为了系统考虑啊,我不杀掉X进程腾个空间,难道让内存爆掉吗?
磁盘申辩:我只不过是接受了X进程的请求,它让我把它拉进去,我本身速度就这样慢,而且有可能加载不成功,我咋整?
X进程申辩:我是受害者呀!我得进磁盘呀!这么重要的程序,有大概几万行的数据怎么能被OS说杀掉就杀掉呢!
最终不知道是谁的错误,所以最后法官将X进程变成了D状态,这个状态不能被杀掉,不能被动!开心了?成功了?恰恰相反,因为如果在OS中有太多的进程都是D状态,那么都是大爷,都不能动,只能让它自己动,那完蛋了,数据量也太大了,所以一般在企业最多也只有两三个D进程,大部分都是S进程,因为有不同的方法将S进程进行保护。

在这里插入图片描述

暂停状态-T(stoped)

可以通过发送 SIGSTOP(kill -19) 信号给进程来停止(T)进程。这个被暂停的进程可以通过再次发送 SIGCONT 信号让进程继续运行。如下图理解:
kill -19 – 暂停
kill -18 – 再次运行
kill -9 – 杀死程序

在这里插入图片描述
这时用kill -9 + 进程PID命令直接终止程序!!!

小知识:
前台进程:S+ 和后台进程:S 的区别:
前台进程:./myproc,输入指令无效bash的命令行解释器就停止工作了,可以被【Ctrl +C】终止
后台进程:./myproc &,可以执行指令,【Ctrl +C】 不能终止进程,退出进程要用kill

kill -l查看命令状态
在这里插入图片描述

死亡进程-X

随时准备被OS回收。此状态只是一个返回状态,无法在任务列表中看到这个状态。因为回收进程是一瞬间发生的事情,我们很难直接捕捉到。

僵尸进程-Z

当一个进程要退出的时候,在系统层面。该进程曾经申请的资源并不是立即被释放,而是要暂时存储一段时间,以供操作系统或者是它的父进程进行读取而如果退出的程序一直不被读取,那么相关数据是不会被释放掉的,一个进程如果是一直在等待着其退出信息被读取,那么我们称这个进程为僵尸进程。

即当子进程要退出的时候,而父进程还在运行,父进程一直不去读取子进程的信息,那么这个子进程一直存在着,但没有意义,那么这个子进程就是僵尸进程僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。

而这个僵尸进程是必需的,我们抽象成一个故事,当在一个地方发生车祸,警察第一时间肯定是保护现场,把整个现场拉一个警戒线,保护整个现场,让亲属来认领这个地方的所有东西。认领成功对应的上的时候。即调用方得知任务的完成情况后,进行后续的操作就很方便了。

例子1:return 0

return 0,这个0是啥用?
实际上这个0是返还给操作系统的,告诉操作系统这个代码顺顺利利执行结束,我们在linux系统重使用echo $?用来查看最近一次进程退出时的退出码。
在这里插入图片描述

例子2:父子进程

监控命令行脚本:

while :; do ps aux | head -1 && ps aux | grep proc | grep -v grep; sleep 1; echo "##############################################"; done

下面代码:子进程杀掉,父进程保留,父进程不回收子进程,看看子进程:
fork函数创建的子进程在打印5次信息后会推出,而父进程一直运行,不会回收子进程:

在这里插入图片描述
在这里插入图片描述

僵尸进程的危害:
1、进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),可父进程如果一直不读取,那子进程就一直处于Z状态。
2、维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护
3、那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费,因为数据结构对象本身就要占用内存,会导致内存泄漏。

孤儿进程

父进程先退出,子进程不退出怎么处理?
父进程先退出,子进程就变成“孤儿进程”
子进程托孤给Init进程(系统本身)领养,当然有Init收回。

在这里插入图片描述
此时进程变成了后台进程,【ctrl+c】停止不了,我们直接kill -9就好

六、进程优先级

基本概念

cpu资源分配的先后顺序,就是指进程的优先权(priority)。
优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。

什么是优先级?

优先级实际上就是获取某种资源的先后顺序,而进程优先级实际上就是进程获取CPU资源分配的先后顺序,也就是值的是优先权,优先权高的进程拥有先执行的权力。

优先级存在的原因?

CPU内资源是有限的,一个CPU一次只能跑一个进程,而进程可以有很多个的,所以需要存在进程优先级来确定进程获取CPU资源的先后顺序。

查看系统进程

ps -l

在这里插入图片描述
打框的重要的信息:
#1、UID : 代表执行者的身份
#2、PID : 代表这个进程的代号
#3、PPID :代表这个进程是由哪个进程发展衍生而来的,即父进程的代号#4、PRI :代表这个进程可被执行的优先级,其值越小越早被执行
#5、NI :代表这个进程的nice值,用来修正优先值的(注意nice值只是用来修正优先值的,它仅仅是一个概念,不是真正的优先级的值)

PRI与NI

#1、PRI代表进程的优先级,通俗点来讲就是进程被CPU执行的先后顺序,该值越小进程的优先级别越高。
#2、NI表示的是nice值,其表示进程可被执行的优先级的修正数值。
#3、PRI(new) = PRI(old)+NI。
#4、当nice值为负值的时候,那么该程序的优先级值将变小,即优先级会变高,越早被执行。
#5、NI即nice的取值范围是-20到19,一共40个级别。
#6、PRI(old)默认为80。

查看进程优先级信息

pa -al // 查看一个进程的PRI和NI值

在这里插入图片描述

用top命令修改进程的nice值

以下要求在root账户下运行!

top命令就相当于windows操作系统中的任务管理器,它能够动态实时的显示系统中进程的占用情况。

命令行输入top

在这里插入图片描述

进入top后按“r”,会要求你输入PID的值:

在这里插入图片描述

输入进程PID,会要求你输入需要调整的nice值:

在这里插入图片描述

输入nice值回车:

在这里插入图片描述

ps -al查看:

在这里插入图片描述

renice命令修改进程nice值

在这里插入图片描述
注意基础的PRI值为80。

为什么nice值处在一个相对较小的范围内呢?
因为优先级再怎么设置,也只能是一种相对的优先级,不能出现绝对的优先级,否则会出现严重的进程饥饿的问题。

操作系统是如何根据优先级开展的调度呢?

总共就四十个位置,操作系统咋确认的调度?
在这里插入图片描述

如上图,我们的CPU内部很聪明,是有一个运行队列的,里面存了两个队列,分别是运行队列和等待队列,我们的PCB先进入到running队列中按照PRI的值在每一个指针后链上,同期waiting队列也在放进去,因为它是running的镜像队列,判断这个队列中跑没跑完只需要用40个比特位的全0即可,这样就是已经满了。
(running中一个PRI为60的更好结束以后,时间片到了,就剥离下来放到waiting队列中等待着上面的running队列跑完它再交换跑即可)

其他四个重要概念

竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发(解决切换的问题)

在这里插入图片描述

并发

问题

为什么函数返回值会被外部拿到呢?
这是由于CPU寄存器能够拿到函数返回值并将其返回,例如return a --> mov eax 10。

系统如何得知我们的进程当前执行到哪行代码了?
程序计数器pc,eip:记录当前进程正在执行指令的下一行指令的地址!

寄存器简单分类

通用寄存器:eax,ebx,ecx,edx……
栈帧:ebp,esp,eip……
状态寄存器:status……

寄存器代表着什么角色?
提高效率,也就是将进程的高频数据放到寄存器中,也就是CPU内的寄存器保存的是进程相关的数据。也就是CPU寄存器里面保存的是进程的临时数据,称之为当前进程的上下文数据。

理解小故事

一个帅小伙X大学生在学校里面学了两年,挂了好几门,于是选择去当兵,运气一好全部通过了,能去当兵了,X小伙开心地跑到宿舍,冲着兄弟们大喊:我去当兵了,结果是连被褥都没收拾,和导员招呼都没打直接跑走了,当兵这两年,学校课堂中一直没有这个人,考试呢也不来,结果是越挂越多,最后被勒令退学,而X小伙不知道啊,两年兵回来以后,寝室自己的床位躺着其他人,到导员那边发现学籍都没了!完蛋!
另一个帅小伙Y大学生去当兵的时候,一脚把门踹开和兄弟们说我去当兵了,然后把被褥收拾完去导员那边说,导员我去当兵了,请帮我保留学籍!接下来Y小伙把档案拿走然后去军队报道,这两年当兵呢,Y小伙因为和学校说过,拿走了档案和行囊,自己好好保存了这些东西,学校不安排考试,两年兵回来后,Y小伙把学籍一交,继续念书,将休学状态改成进修状态,我什么年级段走的时候回来依旧是什么年级段!

进程切换 – 保存上下文和恢复上下文数据的阶段

所以进程从CPU上离开的时候,要将自己的上下文数据保存好甚至带走。保存的目的是为了未来能够恢复!因为进程在CPU跑完以后,倘若不带走自己的上下文数据,那么新的进程进去CPU以后会覆盖老的进程的上下文数据,导致数据丢失,所以需要保存自己的上下文数据保证不丢失。

这些上下文数据都是打包带走放到PCB中!
在这里插入图片描述

总结:到底什么是并发?

一句话:多个进程在一个CPU中高频切换运行!
解析:有很多个进程都抢着进CPU中进行运行,而CPU哪有那么多能力?所以就需要寄存器将其保存进去进行切换,一个运行完了后拿走自己的上下文数据走掉其他进程进来运行,而之前运行完的数据再进来的时候拿着自己的上下文数据再进来就能恢复如初。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2022horse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值