进程线程切换,深度好文|面试官:进程和线程,我只问这19个问题_2414186790的技术博客

 

深度好文|面试官:进程和线程,我只问这19个问题_操作系统

下面隆重推出我呕心沥血,耗时半个月完成的精心力作:

深度好文|面试官:进程和线程,我只问这19个问题_面试_02

0

1

什么是进程?

标准定义:进程是一个具有一定独立功能的程序在一个数据集合上依次动态执行的过程。进程是一个正在执行程序的实例,包括程序计数器、寄存器和程序变量的当前值。

简单来说进程就是一个程序的执行流程,内部保存程序运行所需的资源。

在操作系统中可以有多个进程在运行,可对于CPU来说,同一时刻,一个CPU只能运行一个进程,但在某一时间段内,CPU将这一时间段拆分成更短的时间片,CPU不停的在各个进程间游走,这就给人一种并行的错觉,像CPU可以同时运行多个进程一样,这就是伪并行。

0

2

  进程和程序有什么联系?

一个进程是某种类型的一个活动,它有程序、输入、输出以及状态。单个处理器可以被若干进程共享,它使用某种调度算法决定何时停止一个进程的工作,并转而为另一个进程提供服务。

程序是产生进程的基础

程序的每次运行产生不同的进程

进程是程序功能的体现

通过多次执行,一个程序可对应多个进程;通过调用关系,一个进程可包括多个程序

0

3

进程和程序有什么区别?

进程是动态的,程序是静态的:程序是有序代码的集合,进程是程序的执行。

进程是暂时的,程序是永久的:进程是一个状态变化的过程,程序可长久保存。

进程和程序的组成不同:进程的组成包括程序、数据和进程控制块(进程状态信息)。

0

4

   进程有什么特点?

动态性:可动态的创建和结束进程

并发性:可以被独立的调度并占用处理机并发运行

独立性:不同进程的工作不相互影响

制约性:因访问共享资源或进程间同步而产生制约

0

5

   进程如何创建?

有什么事件会触发进程的创建呢?

系统初始化:当启动操作系统时,通常会创建很多进程,有些是同用户交互并替他们完成工作的前台进程,其它的都是后台进程,后台进程和特定用户没有关系,但也提供某些专门的功能,例如接收邮件等,这种功能的进程也称为守护进程。计划任务是个典型的守护进程,它每分钟运行一次来检查是否有工作需要它完成。如果有工作要做,它就会完成此工作,然后进入休眠状态,直到下一次检查时刻的到来。

正在运行的程序执行了创建进程的系统调用:在一个进程中又创建了一个新的进程,这种情况很常见。

用户请求创建一个新进程:这种情况相信每个人都见过,用电脑时双击某个应用图标,就会有至少一个进程被创建。

一个批处理作业的初始化:这种情形不常见,仅在大型机的批处理系统中应用,用户在这种系统中提交批处理作业,在操作系统认为有资源可运行另一个作业时,它创建一个新的进程,并运行其输入队列中的下一个作业。

归根到底:在UNIX系统中,只有fork系统调用才可以创建新进程,使用方式如下:

#include #include int main() {pid_t id = fork();if (id < 0) {perror("fork\n");} else if (id == 0) {// 子进程printf("子进程\n");} else {// 父进程 printf("父进程\n"); } return 0;}

进程创建之后,父子进程都有各自不同的地址空间,其中一个进程在其地址空间的修改对另一个进程不可见。子进程的初始化空间是父进程的一个副本,这里涉及两个不同地址空间,不可写的内存区是共享的,某些UNIX的实现使程序正文在两者间共享,因为它是不可修改的。

还有一种写时复制共享技术,子进程共享父进程的所有内存,一旦两者之一想要修改部分内存,则这块内存被复制确保修改发生在当前进程的私有内存区域。

0

6

  进程为何终止?

有什么事件会触发进程的终止呢?

正常退出(自愿):进程完成了工作正常终止,UNIX中退出进程的系统调用是exit。

出错退出(自愿):进程发现了错误而退出。可以看如下代码:

#include #include void Func() {if (error) { // 有错误就退出程序exit(1);}}int main() {Func();}

严重错误(非自愿):进程发生了严重的错误而不得不退出,通常是程序的错误导致,例如执行了一条非法指令,引用不存在的内存,或者除数是0等,出现这些错误时进程默认会退出。而有些时候如果用户想自行处理某种类型的错误,发生不同类型错误时进程会收到不同类型的信号,用户注册处理不同信号的函数即可。

被其它进程杀死(非自愿):其它进程执行kill系统调用通知操作系统杀死某个进程。

0

7

操作系统如何进行进程管理?

这里就不得不提到一个数据结构:进程控制块(PCB),操作系统为每个进程都维护一个PCB,用来保存与该进程有关的各种状态信息。进程可以抽象理解为就是一个PCB,PCB是进程存在的唯一标志,操作系统用PCB来描述进程的基本情况以及运行变化的过程,进程的任何状态变化都会通过PCB来体现。

PCB包含进程状态的重要信息,包括程序计数器、堆栈指针、内存分配状况、所打开文件的状态、账号和调度信息,以及其它在进程由运行态转换到就绪态或阻塞态时必须保存的信息,从而保证该进程随后能再次启动,就像从未中断过一样。后一小节会具体介绍PCB。

提到进程管理,有一个概念我们必须要知道,就是中断向量,中断向量是指中断服务程序的入口地址。一个进程在执行过程中可能会被中断无数次,但是每次中断后,被中断的进程都要返回到与中断发生前完全相同的状态。

中断发生后操作系统最底层做了什么呢?

1)硬件压入堆栈程序计数器等;

2)硬件从中断向量装入新的程序计数器;

3)汇编语言过程保存寄存器值;

4)汇编语言过程设置新的堆栈;

5)C中断服务例程运行(典型的读和缓冲输入);

6)调度程序决定下一个将运行的进程;

7)C过程返回到汇编代码;

8)汇编语言过程开始运行新的当前进程。

0

8

进程控制块中存储了什么信息?

进程标识信息:如本进程的标识,本进程的父进程标识,用户标识等。

处理机状态信息保护区:用于保存进程的运行现场信息:

用户可见寄存器:用户程序可以使用的数据,地址等寄存器

控制和状态寄存器:程序计数器,程序状态字

栈指针:过程调用、系统调用、中断处理和返回时需要用到它

进程控制信息:

调度和状态信息:用于操作系统调度进程使用

进程间通信信息:为支持进程间与通信相关的各种标识、信号、信件等,这些信息存在接收方的进程控制块中

存储管理信息:包含有指向本进程映像存储空间的数据结构

进程所用资源:说明由进程打开使用的系统资源,如打开的文件等

有关数据结构连接信息:进程可以连接到一个进程队列中,或连接到相关的其他进程的PCB

0

9

  进程如何进行生命周期管理?

进程创建:

创建进程有三个主要事件:

系统初始化

用户请求创建一个新进程

一个正在运行的进程执行创建进程的系统调用

进程运行:内核选择一个就绪的进程,让它占用处理机并运行,这里就涉及到了进程的调度策略,选择哪个进程调度?为什么选择调度这个进程呢?(莫慌,下面会介绍哈)

进程等待:

在以下情况下进程会等待(阻塞):

请求并等待系统服务,无法马上完成

启动某种操作,无法马上完成

需要的数据没有到达。

注意:进程只能自己阻塞自己,因为只有进程自身才能知道何时需要等待某种事件的发生。

进程唤醒:

进程只能被别的进程或操作系统唤醒,唤醒进程的原因有:

被阻塞进程需要的资源可被满足

被阻塞进程等待的事件到达

将该进程的PCB插入到就绪队列

进程结束:

在以下四种情况下进程会结束:

自愿型正常退出

自愿型错误退出

强制型致命错误退出

强制型被其它进程杀死退出

10

进程都有什么状态?

不同系统设置的进程状态是不同的,多数系统中的进程在生命结束前有三种基本状态,进程只会处于三种基本状态之一:

运行状态:进程正在处理机上运行时就处在运行状态,该时刻进程时钟占用着CPU;

就绪状态:万事俱备,只欠东风,进程已经获得了除处理机之外的一切所需资源,一旦得到处理机就可以运行;就绪态中的进程其实可以运行,但因为其它进程正在占用着CPU而暂时停止运行;

等待状态(阻塞状态):进程正在等待某一事件而暂停运行,等待某个资源或者等待输入输出完成。除非某种外部事件发生,否则阻塞态的进程不能运行;

进程状态变化图如下:

深度好文|面试官:进程和线程,我只问这19个问题_操作系统_03

在操作系统发现进程不能继续运行下去时,进程因为等待输入而被阻塞,进程从运行态转换到阻塞态!

调度程序选择了另一个进程执行时,当前程序就会从运行态转换到就绪态!

被调度程序选择的程序会从就绪态转换到运行态!

当阻塞态的进程等待的一个外部事件发生时,就会从阻塞态转换到就绪态,此时如果没有其他进程运行时,则立刻从就绪态转换到运行态!

某些系统设置下进程还会有其它状态:

创建状态:进程正在被创建还没被转到就绪状态之前的状态;

结束状态:进程正在从系统中消失时的状态。

有些与进程管理相关的系统调用读者有必要了解一下:

pid=fork(); // 创建一个与父进程一样的子进程pid=waitpid(); // 等待子进程终止s=execve(); // 替换进程的核心映像exit(); // 终止进程运行并返回状态值s=sigaction(); // 定义信号处理的动作s=sigprocmask(); // 检查或更换信号掩码s=sigpending(); // 获得阻塞信号集合s=sigsuspend(); // 替换信号掩码或挂起进程alarm(); // 设置定时器pause(); // 挂起调用程序直到下一个信号出现

11

什么是进程挂起?为什么会出现进程挂起?

进程挂起就是为了合理且充分的利用系统资源,把一个进程从内存转到外存。进程在挂起状态时,意味着进程没有占用内存空间,处在挂起状态的进程映射在磁盘上。进程挂起通常有两种状态:

阻塞挂起状态:进程在外存并等待某事件的出现;

就绪挂起状态:进程在外存,但只要进入内存即可运行。

有什么与进程挂起相关的状态转换?

进程挂起可能有以下几种情况:

阻塞到阻塞挂起:没有进程处于就绪状态或就绪进程要求更多内存资源时,会进行这种转换,以提交新进程或运行就绪进程;

就绪到就绪挂起:当有高优先级阻塞进程或低优先级就绪进程时,系统会选择挂起低优先级就绪进程;

运行到就绪挂起:对于抢占式分时系统,当有高优先级阻塞挂起进程因事件出现而进入就绪挂起时,系统可能会把运行进程转到就绪挂起状态;

阻塞挂起到就绪挂起:当有阻塞挂起进程有相关事件出现时,系统会把阻塞挂起进程转换为就绪挂起进程。

有进程挂起那就有进程解挂:指一个进程从外存转到内存,相关状态有:

就绪挂起到就绪:没有就绪进程或就绪挂起进程优先级高于就绪进程时,就会进行这种转换;

阻塞挂起到阻塞:当一个进程释放足够内存时,系统会把一个高优先级阻塞挂起进程转换为阻塞进程。

12

  什么是进程调度?操作系统对于进程调度都有什么策略?

当系统中有多个进程同时竞争CPU,如果只有一个CPU可用,那同一时刻只会有一个进程处于运行状态,操作系统必须要选择下一个要运行的是哪个进程,在操作系统中,完成选择工作的这部分称为调度程序,该程序使用的算法称作调度算法。

什么时候进行调度?

系统调用创建一个新进程后,需要决定是运行父进程还是运行子进程

一个进程退出时需要做出调度决策,需要决定下一个运行的是哪个进程

当一个进程阻塞在I/O和信号量或者由于其它原因阻塞时,必须选择另一个进程运行

当一个I/O中断发生时,如果中断来自IO设备,而该设备现在完成了工作,某些被阻塞的等待该IO的进程就成为可运行的就绪进程了,是否让新就绪的进程运行,或者让中断发生时运行的进程继续运行,或者让某个其它进程运行,这就取决于调度程序的抉择了。

调度算法可以分类:

非抢占式调度算法:挑选一个进程,然后让该进程运行直至被阻塞,或者直到该进程自动释放CPU,即使该进程运行了若干个小时,它也不会被强迫挂起。这样做的结果是,在时钟中断发生时不会进行调度,在处理完时钟中断后,如果没有更高优先级的进程等待,则被中断的进程会继续执行。简单来说,调度程序必须等待事件结束。

非抢占方式引起进程调度的条件:

进程执行结束,或发生某个事件而不能继续执行

正在运行的进程因有I/O请求而暂停执行

进程通信或同步过程中执行了某些原语操作(wait、block等)

抢占式调度算法:挑选一个进程,并且让该进程运行某个固定时段的最大值。如果在该时段结束时,该进程仍在运行,它就被挂起,而调度程序挑选另一个进程运行,进行抢占式调度处理,需要在时间间隔的末端发生时钟中断,以便CPU控制返回给调度程序,如果没有可用的时钟,那么非抢占式调度就是唯一的选择。简单来说,就是当前运行的进程在事件没结束时就可以被换出,防止单一进程长时间独占CPU资源。下面会介绍很多抢占式调度算法:优先级算法、短作业优先算法、轮转算法等。

调度策略:不同系统环境下有不同的调度策略算法。调度算法也是有KPI的,对调度算法首先提的需求就是:

公平:调度算法需要给每个进程公平的CPU份额,相似的进程应该得到相似的服务,对一个进程给予较其它等价的进程更多的CPU时间是不公平的,被普通水平的应届生工资倒挂也是不公平的!

执行力:每一个策略必须强制执行,需要保证规定的策略一定要被执行。

平衡:需要保证系统的所有部分尽可能都忙碌

但是因为不同的应用有不同的目标,不同的系统中,调度程序的优化也是不同的,大体可以分为三种环境:

批处理系统

批处理系统的管理者为了掌握系统的工作状态,主要关注三个指标:

吞吐量:是系统每小时完成的作业数量

周转时间:指从一个作业提交到完成的平均时间

CPU利用率:尽可能让CPU忙碌,但又不能过量

调度算法:

先来先服务

先来后到嘛,就像平时去商店买东西需要排队一样,使用该算法,进程按照它们请求CPU的顺序来使用CPU,该算法最大的优点就是简单易于实现,太容易的不一定是好的,该算法也有很大的缺点:平均等待时间波动较大,时间短的任务可能排队排在了时间长的任务后面。举个生活中的例子,排着队去取快递,如果每个人都很快取出来快递还好,如果前面有几个人磨磨唧唧到快递柜前才拿出手机打开app,再找半分钟它的取件码,就会严重拖慢后面的人取快递的速度,同理排着队的进程如果每个进程都很快就运行完还好,如果其中有一个得到了CPU的进程运行时候磨磨唧唧很长时间都运行不完,那后面的进程基本上就没有机会运行了!

最短作业优先

该调度算法是非抢占式的算法,每个进程执行期间不会被打断,每次都选择执行时间最短的进程来调度,但问题来了,操作系统怎么可能知道进程具体的执行时间呢,所以该算法注定是基于预测性质的理想化算法,而且有违公平性,而且可能导致运行时间长的任务得不到调度。

最短剩余时间优先

该调度算法是抢占式的算法,是最短作业优先的抢占版本,在进程运行期间,如果来了个更短时间的进程,那就转而去把CPU时间调度给这个更短时间的进程,它的缺点和最短作业优先算法类似。

交互式系统

对于交互系统最重要的指标就是响应时间和均衡性啦:

响应时间:一个请求被提交到产生第一次响应所花费的时间。你给别人发微信别人看后不回复你或者几个小时后才回复你,你是什么感受,这还是交互式吗?

均衡性:减少平均响应时间的波动。需要符合固有期望和预期,你给别人发微信,他有时候秒回复,有时候几个小时后才回复。在交互式系统中,可预测性比高差异低平均更重要。

调度算法:

轮转调度

每个进程被分配一个时间段,称为时间片,即CPU做到雨露均沾,轮流翻各个进程的牌子,这段时间宠幸进程A,下一段时间宠幸进程B,再下一段时间宠幸进程C,确保每个进程都可以获得CPU时间,如果CPU时间特别短的话,在外部看来像是同时宠幸了所有进程一样。那么问题来了,这个时间片究竟多长时间好呢?如果时间片设的太短会导致过多的进程切换,频繁的上下文切换会降低CPU效率,而如果时间片设的太长又可能对短的交互请求的响应时间变长,通常将时间片设为20-50ms是个比较合理的折中,大佬们的经验规则时维持上下文切换的开销处于1%以内。

优先级调度

上面的轮转调度算法是默认每个进程都同等重要,都有相同优先级,然而有时候进程需要设置优先级,例如某些播放视频的前台进程可以优先于某些收发邮件的后台守护进程被调度,在优先级调度算法中,每个优先级都有相应的队列,队列里面装着对应优先级的进程,首先在高优先级队列中进行轮转调度,当高优先级队列为空时,转而去低优先级队列中进行轮转调度,如果高优先级队列始终不为空,那么低优先级的进程很可能就会饥饿到很久不能被调度。

多级队列

多级队列算法与优先级调度算法不同,优先级算法中每个进程分配的是相同的时间片,而在多级队列算法中,不同队列中的进程分配给不同的时间片,当一个进程用完分配的时间片后就移动到下一个队列中,这样可以更好的避免上下文频繁切换。举例:有一个进程需要100个时间片,如果每次调度都给分配一个时间片,则需要100次上下文切换,这样CPU运行效率较低,通过多级队列算法,可以考虑最开始给这个进程分配1个时间片,然后被换出,下次分给它2个时间片,再换出,之后分给它4、8、16、64个时间片,这样分配的话,该进程只需要7次交换就可以运行完成,相比100次上下文切换运行效率高了不少,但顾此就会失彼,那些需要交互的进程得到响应的速度就会下降。

最短进程优先

交互式系统中应用最短进程优先算法其实是非常适合的,每次都选择执行时间最短的进程进行调度,这样可以使任务的响应时间最短,但这里有个任务,还没有运行呢,我怎么知道进程的运行时间呢?根本没办法非常准确的再当前可运行进程中找出最短的那个进程。有一种办法就是根据进程过去的行为进行预测,但这能证明是个好办法吗?

保证调度

这种调度算法就是向用户做出明确的可行的性能保证,然后去实现它。一种很实际的可实现的保证就是确保N个用户中每个用户都获得CPU处理能力的1/N,类似的,保证N个进程中每个进程都获得1/N的CPU时间。

彩票调度

彩票调度算法基本思想是为进程提供各种资源(CPU时间)的彩票,一旦需要做出调度决策时,就随机抽出一张彩票,拥有该彩票的进程获得该资源,很明显,拥有彩票越多的进程,获得资源的可能性越大。该算法在程序喵看来可以理解为股票算法,将CPU的使用权分成若干股,假设共100股分给了3个进程,给这些进程分别分配20、30、50股,那么它们大体上会按照股权比例(20:30:50)划分CPU的使用。

公平分享调度

假设有系统两个用户,用户1启动了1个进程,用户2启动了9个进程,如果使用轮转调度算法,那么用户1将获得10%的CPU时间,用户2将获得90%的CPU时间,这对用户来说公平吗?如果给每个用户分配50%的CPU时间,那么用户2中的进程获得的CPU时间明显比用户1中的进程短,这对进程来说公平吗?这就取决于怎么定义公平啦?

实时系统

实时系统顾名思义,最关键的指标当然是实时啦:

满足截止时间:需要在规定deadline前完成作业;

可预测性:可预测性是指在系统运行的任何时刻,在任何情况下,实时系统的资源调配策略都能为争夺资源的任务合理的分配资源,使每个实时任务都能得到满足。

调度算法分类:

硬实时

必须在deadline之前完成工作,如果delay,可能会发生灾难性或发生严重的后果;

软实时

必须在deadline之前完成工作,但如果偶尔delay了,也可以容忍。

调度算法:

单调速率调度

采用抢占式、静态优先级的策略,调度周期性任务。

每个任务最开始都被配置好了优先级,当较低优先级的进程正在运行并且有较高优先级的进程可以运行时,较高优先级的进程将会抢占低优先级的进程。在进入系统时,每个周期性任务都会分配一个优先级,周期越短,优先级越高。这种策略的理由是:更频繁的需要CPU的任务应该被分配更高的优先级。

最早截止时间调度

根据截止时间动态分配优先级,截止时间越早的进程优先级越高。

该算法中,当一个进程可以运行时,它应该向操作系统通知截止时间,根据截止时间的早晚,系统会为该进程调整优先级,以便满足可运行进程的截止时间要求。它与单调速率调度算法的区别就是一个是静态优先级,一个是动态优先级。

如何配置调度策略?

调度算法有很多种,各有优缺点,操作系统自己很少能做出最优的选择,那么可以把选择权交给用户,由用户根据实际情况来选择适合的调度算法,这就叫策略与机制分离,调度机制位于内核,调度策略由用户进程决定,将调度算法以某种形式参数化,由用户进程来选择参数从而决定内核使用哪种调度算法。

13

操作系统怎么完成进程调度?

进程的每次变化都会有相应的状态,而操作系统维护了一组状态队列,表示系统中所有进程的当前状态;不同的状态有不同的队列,有就绪队列阻塞队列等,每个进程的PCB都根据它的状态加入到相应的队列中,当一个进程的状态发生变化时,它的PCB会从一个状态队列中脱离出来加入到另一个状态队列。

深度好文|面试官:进程和线程,我只问这19个问题_面试_04

注意图中同一种状态为什么有多个队列呢?因为进程有优先级概念,相同状态的不同队列的优先级不同。

14

   什么是线程?

线程是进程当中的一条执行流程,这几乎就是进程的定义,一个进程内可以有多个子执行流程,即线程。可以从两个方面重新理解进程:

从资源组合的角度:进程把一组相关的资源组合起来,构成一个资源平台环境,包括地址空间(代码段、数据段),打开的文件等各种资源

从运行的角度:代码在这个资源平台上的执行流程,然而线程貌似也是这样,但是进程比线程多了资源内容列表样式:那就有一个公式:进程 = 线程 + 共享资源

15

  为什么使用线程?

因为要并发编程,在许多情形中同时发生着许多活动,而某些活动有时候会被阻塞,通过将这些活动分解成可以准并行运行的多个顺序流程是必须的,而如果使用多进程方式进行并发编程,进程间的通信也很复杂,并且维护进程的系统开销较大:创建进程时分配资源建立PCB,撤销进程时回收资源撤销PCB,进程切换时保存当前进程的状态信息。所以为了使并发编程的开销尽量小,所以引入多线程编程,可以并发执行也可以共享相同的地址空间。并行实体拥有共享同一地址空间和所有可用数据的能力,这是多进程模型所不具备的能力。

使用线程有如下优点:

可以多个线程存在于同一个进程中

各个线程之间可以并发的执行

各个线程之间可以共享地址空间和文件等资源

线程比进程更轻量级,创建线程撤销线程比创建撤销进程要快的多,在许多系统中,创建一个线程速度是创建一个进程速度的10-100倍。

如果多个线程是CPU密集型的,并不能很好的获得更好的性能,但如果多个线程是IO密集型的,线程存在着大量的计算和大量的IO处理,有多个线程允许这些活动彼此重叠进行,从而会加快整体程序的执行速度。

但也有缺点:

一旦一个线程崩溃,会导致其所属进程的所有线程崩溃。

由于各个线程共享相同的地址空间,那么读写数据可能会导致竞争关系,因此对同一块数据的读写需要采取某些同步机制来避免线程不安全问题。

16

   什么时候用进程、线程?

进程是资源分配单位,线程是CPU调度单位;

进程拥有一个完整的资源平台,而线程只独享必不可少的资源,如寄存器和栈;

线程同样具有就绪阻塞和执行三种基本状态,同样具有状态之间的转换关系;

线程能减少并发执行的时间和空间开销:

线程的创建时间比进程短

线程的终止时间比进程短

同一进程内的线程切换时间比进程短

由于同一进程的各线程间共享内存和文件资源,可直接进行不通过内核的通信

结论:可以在强调性能时候使用线程,如果追求更好的容错性可以考虑使用多进程,google浏览器据说就是用的多进程编程。在多CPU系统中,多线程是有益的,在这样的系统中,通常情况下可以做到真正的并行。

C/C++中如何使用多线程编程?

POSIX使用如下线程封装函数来操作线程:

pthread_create 创建一个新线程pthread_exit 结束调用的线程pthread_join 等待一个特定的线程退出pthread_yield释放CPU来运行另外一个线程pthread_attr_init创建并初始化一个线程的属性结构pthread_attr_destroy 删除一个线程的属性结构

后两个函数是有关线程属性的调用。pthread_attr_init建立关联一个线程的属性结构并初始化成默认值,这些值(优先级等)可以通过修改属性结构中的对应值来改变;pthread_attr_destroy会删除一个线程的属性结构,释放它占用的内存,它不会影响调用它的线程,线程依然会继续存在。

C++中有std::thread和async,可以很方便的操作多线程,示例代码如下:

void F() {coutmax_size) {cout
进程和线程基础知识全家桶,30 张图一套带走 - 敖丙 ...【程序员必备小知识-性能基础11】进程的上下文切换详解 - 掘金并发编程-进程线程相关概念,multiprocessing,threading ...线程上下文切换和进程上下文切换的区别 - CSDN开发云对比进程切换与同一进程内的线程间切换的异同?_百度知道Java多线程 - 静守己心&笑淡浮华 - 博客园怎么理解Linux的CPU上下文切换 - 编程宝库深度好文|面试官:进程和线程,我只问这19个问题不同性能测试工具的并发模式有哪些_进程_运行_代理操作系统之进程线程(二者的区别,进程的状态切换、创建、终止、上下文切换Python 基础 之 python 中 进程线程、协程对比 区别和联系面试必问:进程线程有什么区别?线程进程的关系进程上下文切换与和线程上下文切换有什么不同?进程线程合集以及实例进程线程的区别(操作系统级别解析)进程与线程-2、用户级线程切换过程CPU分析系列--vmstat/pidstat -wt分析进程/线程上下文切换造成的性能瓶颈线程上下文切换进程线程、协程和管程的区别Java与线程进程线程的分配策略【杂记】线程调度为什么比进程调度更少开销?进程线程和并行并发一文讲透 “进程线程、协程”操作系统(四) -- 用户级线程与核心级线程线程切换切换线程对cpu资源的浪费进程线程概念为什么切换线程切换进程开销小CPU与核心及进程线程认识【哈工大李治军】操作系统课程笔记5:多线程、用户线程和内核线程 +【实验 5】基于内核栈切换进程切换线程切换以及线程进程之间关系操作系统 - 进程 / 线程 / 协程 - 学习/实践【NDK】Java和Native相互调用的“线程切换进程切换过程进程切换开销大的原因Android中多线程切换的几种方法进程线程的区别(c++)【操作系统】进程线程调度
为什么线程切换比进程切换快进程线程上下文切换进程切换为什么比线程慢线程切换 进程切换进程切换 页表进程和线程的切换流程线程切换和进程切换的区别线程切换为什么比进程切换开销小进程线程切换区别是什么进程线程切换的代价进程切换 线程切换线程 切换线程切换会引起进程切换进程的切换进程切换和线程切换的区别进程调度和进程切换cpu线程切换什么叫进程切换泰拉瑞亚内置修改器手机版字符串怎么定义少林寺传奇第二部三大绝世高手水瓶座的幸运数字和幸运色是多少汽车配件零件号怎么分左右怎么回复别人的结婚邀请器官臣不以为喜翻译粉虱的危害电脑适用的录屏软件问别人什么时候结婚该怎么问