前言

为了方便大家理解进线程的工作流程及运行状态,先来看一篇小故事:

我们写好的一行行代码,为了让其工作起来,我们还得把它送进城(进程)里,那既然进了城里,那肯定不能胡作非为了。

但是城里有城里的规矩,城中有个专门管辖你们的城管(操作系统),人家让你休息就休息,让你工作就工作,毕竟摊位(CPU)就一个,每个人都要占这个摊位来工作,城里要工作的人多着去了。

所以城管为了公平起见,它使用一种策略(调度)方式,给每个人一个固定的工作时间(时间片),时间到了就会通知你去休息而换另外一个人上场工作。

另外,在休息时候你也不能偷懒,要记住工作到哪了,不然下次到你工作了,你忘记工作到哪了,那还怎么继续?

有的人,可能还进入了县城(线程)工作,这里相对轻松一些,在休息的时候,要记住的东西相对较少,而且还能共享城里的资源。

接下来重点给大家介绍操作系统中进程和线程的工作原理及它们之间的区别:
111

正文

一、进程

我们编写的代码只是一个存储在硬盘中的静态文件,通过编译后就会生成二进制可执行文件,当我们运行这个可执行文件后,它会被加载到内存中,接着 CPU 会执行程序中的每一条指令,那么这个运行中的程序就被称为「进程」

现在我们考虑有一个会读取硬盘文件数据的程序被执行了,那么当运行到读取文件的指令时,就会去从硬盘读取数据,但是硬盘的读写速度是非常慢的,那么在这个时候如果 CPU 傻傻的等硬盘返回数据的话,那 CPU 的利用率是非常低的。

做个类比,你去煮开水时,你不会傻傻的站在那等水壶烧开(除非你真的没有其它的事情要去做),我们可以在水壶烧开之前去做其他事情。当水壶烧开了,我们自然就会听到“嘀嘀嘀”的声音,于是再把烧开的水倒入到水杯里就好了。

所以,当进程要从硬盘读取数据时,CPU 不需要阻塞等待数据的返回,而是去执行另外的进程。当硬盘数据返回时,CPU 会收到个中断,于是 CPU 再继续运行这个进程。
222
这种多个程序交替执行的思想,就有 CPU 管理多个进程的初步想法。

对于一个支持多进程的系统,CPU 会从一个进程快速切换至另一个进程,其间每个进程各运行几十或几百个毫秒。

虽然单核的 CPU 在某一个瞬间,只能运行一个进程。但在 1 秒钟期间,它可能会运行多个进程,这样就产生并行的错觉,实际上这是并发

并行和并发的区别:
3
进程和程序之间的关系类比如下:

到了晚饭时间,一对小情侣肚子都咕咕叫了,于是男生见机行事,就想给女生做晚饭,所以他就在网上找了辣子鸡的菜谱,接着买了一些鸡肉、辣椒、香料等材料,然后边看边学边做这道菜。
4
突然,女生说她想喝可乐,那么男生只好把做菜的事情暂停一下,并在手机菜谱标记做到哪一个步骤,把状态信息记录了下来。

然后男生听从女生的指令,跑去楼下买了一瓶冰可乐后,又回到厨房继续做菜。

这体现了,CPU 可以从一个进程(做菜)切换到另外一个进程(买可乐),在切换前必须要记录当前进程中运行的状态信息,以备下次切换回来的时候可以恢复执行

所以,可以发现进程有着「运行 - 暂停 - 运行」的活动规律。

1.1 进程的状态

在上面,我们知道了进程有着「运行 - 暂停 - 运行」的活动规律。一般说来,一个进程并不是自始至终连续不停地运行的,它与并发执行中的其他进程的执行是相互制约的。

它有时处于运行状态,有时又由于某种原因而暂停运行处于等待状态,当使它暂停的原因消失后,它又进入准备运行状态。

所以,在一个进程的活动期间至少具备三种基本状态,即运行状态就绪状态阻塞状态
5
上图中各个状态的意义:

  • 运行状态(Runing):该时刻进程占用 CPU;

  • 就绪状态(Ready):可运行,但因为其他进程正在运行而暂停停止;

  • 阻塞状态(Blocked):该进程正在等待某一事件发生(如等待输入/输出操作的完成)而暂时停止运行,这时,即使给它CPU控制权,它也无法运行;

当然,进程另外两个基本状态:

  • 创建状态(new):进程正在被创建时的状态;

  • 结束状态(Exit):进程正在从系统中消失时的状态;

于是,一个完整的进程状态的变迁如下图:
6
再来详细说明一下进程的状态变迁:

  • NULL -> 创建状态:一个新进程被创建时的第一个状态;

  • 创建状态 -> 就绪状态:当进程被创建完成并初始化后,一切就绪准备运行时,变为就绪状态,这个过程是很快的;

  • 就绪态 -> 运行状态:处于就绪状态的进程被操作系统的进程调度器选中后,就分配给 CPU 正式运行该进程;

  • 运行状态 -> 结束状态:当进程已经运行完成或出错时,会被操作系统作结束状态处理;

  • 运行状态 -> 就绪状态:处于运行状态的进程在运行过程中,由于分配给它的运行时间片用完,操作系统会把该进程变为就绪态,接着从就绪态选中另外一个进程运行;

  • 运行状态 -> 阻塞状态:当进程请求某个事件且必须等待时,例如请求 I/O 事件;

  • 阻塞状态 -> 就绪状态:当进程要等待的事件完成时,它从阻塞状态变到就绪状态;

另外,还有一个状态叫 挂起状态 ,它表示进程没有占有物理内存空间。这跟阻塞状态不一样,阻塞状态是等待某个事件的返回。

由于虚拟内存管理原因,进程所使用的空间可能并没有映射到物理内存,而是在硬盘上,这时进程就会出现挂起状态,另外调用 sleep 也会被挂起。
7
挂起状态可以分为两种:

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

就绪挂起状态:进程在外存(硬盘),但只要进入内存,即刻立刻运行;

这两种挂起状态加上前面的五种状态,就变成了七种状态变迁(留给我的颜色不多了),见如下图:
8

1.2 进程控制结构

在操作系统中,是用 进程控制块(process control block,PCB)数据结构来描述进程的。

那 PCB 是什么呢?

PCB 是进程存在的唯一标识,这意味着一个进程的存在,必然会有一个 PCB,如果进程消失了,那么 PCB 也会随之消失。

PCB具体包含什么信息?
  • 进程描述信息

    进程标识符:标识各个进程,每个进程都有一个并且唯一的标识符;

    用户标识符:进程归属的用户,用户标识符主要为共享和保护服务;

  • 进程控制和管理信息:进程当前状态,如 new、ready、running、waiting 或 blocked 等;

  • 进程优先级:进程抢占 CPU 时的优先级;

  • 资源分配清单:有关内存地址空间或虚拟地址空间的信息,所打开文件的列表和所使用的 I/O 设备信息。

  • CPU 相关信息:CPU 中各个寄存器的值,当进程被切换时,CPU 的状态信息都会被保存在相应的 PCB 中,以便进程重新执行时,能从断点处继续执行。

可见,PCB 包含信息还是比较多的。

每个PCB是如何组织的?

通常是通过链表的方式进行组织,把具有相同状态的进程链在一起,组成各种队列。比如:

  • 将所有处于就绪状态的进程链在一起,称为就绪队列;

  • 把所有因等待某事件而处于等待状态的进程链在一起就组成各种阻塞队列;

  • 另外,对于运行队列在单核 CPU 系统中则只有一个运行指针了,因为单核 CPU 在某个时间,只能运行一个程序。

那么,就绪队列和阻塞队列链表的组织形式如下图:
9
除了链接的组织方式,还有索引方式,它的工作原理:将同一状态的进程组织在一个索引表中,索引表项指向相应的 PCB,不同状态对应不同的索引表。

一般会选择链表,因为可能面临进程创建,销毁等调度导致进程状态发生变化,所以使用链表能够更加灵活的插入和删除。

1.3 进程的控制

我们熟知了进程的状态变迁和进程的数据结构 PCB 后,再来看看进程的创建、终止、阻塞、唤醒的过程,这些过程也就是进程的控制。

01 创建进程

操作系统允许一个进程创建另一个进程,而且允许子进程继承父进程所拥有的资源,当子进程被终止时,其在父进程处继承的资源应当还给父进程。同时,终止父进程时同时也会终止其所有的子进程。

创建进程的过程如下:

为新进程分配一个唯一的进程标识号,并申请一个空白的 PCB,PCB 是有限的,若申请失败则创建失败;

为进程分配资源,此处如果资源不足,进程就会进入等待状态,以等待资源;

初始化 PCB;

如果进程的调度队列能够接纳新进程,那就将进程插入到就绪队列,等待被调度运行;

02 终止进程

进程可以有 3 种终止方式:正常结束、异常结束以及外界干预(信号 kill 掉)。

终止进程的过程如下:

查找需要终止的进程的 PCB;

如果处于执行状态,则立即终止该进程的执行,然后将 CPU 资源分配给其他进程;

如果其还有子进程,则应将其所有子进程终止;

将该进程所拥有的全部资源都归还给父进程或操作系统;

将其从 PCB 所在队列中删除;

03 阻塞进程

当进程需要等待某一事件完成时,它可以调用阻塞语句把自己阻塞等待。而一旦被阻塞等待,它只能由另一个进程唤醒。

阻塞进程的过程如下:

找到将要被阻塞进程标识号对应的 PCB;

如果该进程为运行状态,则保护其现场,将其状态转为阻塞状态,停止运行;

将该 PCB 插入的阻塞队列中去;

04 唤醒进程

进程由「运行」转变为「阻塞」状态是由于进程必须等待某一事件的完成,所以处于阻塞状态的进程是绝对不可能叫醒自己的

如果某进程正在等待 I/O 事件,需由别的进程发消息给它,则只有当该进程所期待的事件出现时,才由发现者进程用唤醒语句叫醒它。

唤醒进程的过程如下:

在该事件的阻塞队列中找到相应进程的 PCB;

将其从阻塞队列中移出,并置其状态为就绪状态;

把该 PCB 插入到就绪队列中,等待调度程序调度;

进程的阻塞和唤醒是一对功能相反的语句,如果某个进程调用了阻塞语句,则必有一个与之对应的唤醒语句

1.4 进程的上下文切换

各个进程之间是共享 CPU 资源的,在不同的时候进程之间需要切换,让不同的进程可以在 CPU 执行,那么从这个进程切换到另一个进程的运行称为进程的上下文切换。

首先我们来了解一下CPU的上下文切换:

大多数操作系统都是多任务,通常支持大于 CPU 数量的任务同时运行。实际上,这些任务并不是同时运行的,只是因为系统在很短的时间内,让各个任务分别在 CPU 运行,于是就造成同时运行的错觉。

任务是交给 CPU 运行的,那么在每个任务运行前,CPU 需要知道任务从哪里加载,又从哪里开始运行。

所以,操作系统需要事先帮 CPU 设置好 CPU 寄存器程序计数器

CPU 寄存器是 CPU 内部一个容量小,但是速度极快的内存(缓存)。我举个例子,寄存器像是你的口袋,内存像你的书包,硬盘则是你家里的柜子,如果你的东西存放到口袋,那肯定是比你从书包或家里柜子取出来要快的多。

再来,程序计数器则是用来存储 CPU 正在执行的指令位置、或者即将执行的下一条指令位置。

所以说,CPU 寄存器和程序计数器是 CPU 在运行任何任务前,所必须依赖的环境,这些环境就叫做 CPU 上下文

既然知道了什么是 CPU 上下文,那理解 CPU 上下文切换就不难了。

CPU 上下文切换就是先把前一个任务的 CPU 上下文(CPU 寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务

系统内核会存储保持下来的上下文信息,当此任务再次被分配给 CPU 运行时,CPU 会重新加载这些上下文,这样就能保证任务原来的状态不受影响,让任务看起来还是连续运行。

上面说到所谓的「任务」,主要包含进程线程中断。所以,可以根据任务的不同,把 CPU 上下文切换分成:进程上下文切换、线程上下文切换和中断上下文切换。

进程的上下文切换到底是切换什么?

进程是由内核管理和调度的,所以进程的切换只能发生在内核态。

所以,进程的上下文切换不仅包含了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的资源

通常,会把交换的信息保存在进程的 PCB,当要运行另外一个进程的时候,我们需要从这个进程的 PCB 取出上下文,然后恢复到 CPU 中,这使得这个进程可以继续执行,如下图所示:
10
大家需要注意,进程的上下文开销是很关键的,我们希望它的开销越小越好,这样可以使得进程可以把更多时间花费在执行程序上,而不是耗费在上下文切换。

什么时候会发生进程上下文切换?
  • 为了保证所有进程可以得到公平调度,CPU 时间被划分为一段一段的时间片,这些时间片再被轮流分配给各个进程。这样,当某个进程的时间片耗尽了,就会被系统挂起,切换到其它正在等待 CPU 的进程运行;

  • 进程在系统资源不足(比如内存不足)时,要等到资源满足后才可以运行,这个时候进程也会被挂起,并由系统调度其他进程运行;

  • 当进程通过睡眠函数 sleep 这样的方法将自己主动挂起时,自然也会重新调度;

  • 当有优先级更高的进程运行时,为了保证高优先级进程的运行,当前进程会被挂起,由高优先级进程来运行;

  • 发生硬件中断时,CPU 上的进程会被中断挂起,转而执行内核中的中断服务程序;

以上,就是发生进程上下文切换的常见场景了。

二、线程

在早期的操作系统中都是以进程作为独立运行的基本单位,直到后面,计算机科学家们又提出了更小的能独立运行的基本单位,也就是线程

2.1 为什么使用线程

我们举个例子,假设你要编写一个视频播放器软件,那么该软件功能的核心模块有三个:

  • 从视频文件当中读取数据;

  • 对读取的数据进行解压缩;

  • 把解压缩后的视频数据播放出来;

对于单进程的实现方式,我想大家都会是以下这个方式:
11
对于单进程的这种方式,存在以下问题:

  • 播放出来的画面和声音会不连贯,因为当 CPU 能力不够强的时候,Read 的时候可能进程就等在这了,这样就会导致等半天才进行数据解压和播放;

  • 各个函数之间不是并发执行,影响资源的使用效率;

那改进成多进程的方式:
12
对于多进程的这种方式,依然会存在问题:

  • 进程之间如何通信,共享数据?

  • 维护进程的系统开销较大,如创建进程时,分配资源、建立 PCB;终止进程时,回收资源、撤销 PCB;进程切换时,保存当前进程的状态信息;

那到底如何解决呢?需要有一种新的实体,满足以下特性:

  • 实体之间可以并发运行;

  • 实体之间共享相同的地址空间;

这个新的实体,就是线程( Thread ),线程之间可以并发运行且共享相同的地址空间。

2.2 什么是线程?

线程是进程当中的一条执行流程。

同一个进程内多个线程之间可以共享代码段、数据段、打开的文件等资源,但每个线程都有独立一套的寄存器和栈,这样可以确保线程的控制流是相对独立的
13

线程有哪些优缺点?

线程的优点:

  • 一个进程中可以同时存在多个线程;

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

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

线程的缺点:

  • 当进程中的一个线程奔溃时,会导致其所属进程的所有线程奔溃。

举个例子,对于游戏的用户设计,则不应该使用多线程的方式,否则一个用户挂了,会影响其他同个进程的线程。

2.3 线程与进程的比较

线程与进程的比较如下:

  • 进程是资源(包括内存、打开的文件等)分配的最小单位,线程是 CPU 调度的最小单位;

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

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

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

对于,线程相比进程能减少开销,体现在:

  • 线程的创建时间比进程快,因为进程在创建的过程中,还需要资源管理信息,比如内存管理信息、文件管理信息,而线程在创建的过程中,不会涉及这些资源管理信息,而是共享它们;

  • 线程的终止时间比进程快,因为线程释放的资源相比进程少很多;

  • 同一个进程内的线程切换比进程切换快,因为线程具有相同的地址空间(虚拟内存共享),这意味着同一个进程的线程都具有同一个页表,那么在切换的时候不需要切换页表。而对于进程之间的切换,切换的时候要把页表给切换掉,而页表的切换过程开销是比较大的;

  • 由于同一进程的各线程间共享内存和文件资源,那么在线程之间数据传递的时候,就不需要经过内核了,这就使得线程之间的数据交互效率更高了;

所以,线程比进程不管是时间效率,还是空间效率都要高。

2.4 线程的上下文切换

在前面我们知道了,线程与进程最大的区别在于:线程是调度的基本单位,而进程则是资源拥有的基本单位。

所以,所谓操作系统的任务调度,实际上的调度对象是线程,而进程只是给线程提供了虚拟内存、全局变量等资源

对于线程和进程,我们可以这么理解:

  • 当进程只有一个线程时,可以认为进程就等于线程;

  • 当进程拥有多个线程时,这些线程会共享相同的虚拟内存和全局变量等资源,这些资源在上下文切换时是不需要修改的;

另外,线程也有自己的私有数据,比如寄存器等,这些在上下文切换时也是需要保存的

线程上下文切换的是什么?

这还得看线程是不是属于同一个进程:

  • 当两个线程不属于同一个进程,则切换的过程就跟进程上下文切换一样;

  • 当两个线程是属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据;

所以,线程的上下文切换相比进程,开销要小很多。

2.5 线程的实现

主要有三种线程的实现方式:

  • 用户线程(User Thread):在用户空间实现的线程,不是由内核管理的线程,是由用户态的线程库来完成线程的管理;

  • 内核线程(Kernel Thread):在内核中实现的线程,是由内核管理的线程;

  • 轻量级进程(LightWeight Process):在内核中来支持用户线程;

那么,这还需要考虑一个问题,用户线程和内核线程的对应关系。

首先,第一种关系是多对一的关系,也就是多个用户线程对应同一个内核线程
14
第二种是一对一的关系,也就是一个用户线程对应一个内核线程
15
第三种是多对多的关系,也就是多个用户线程对应到多个内核线程
16

用户线程如何理解?存在什么优势和缺陷?

用户线程是基于用户态的线程管理库来实现的,那么线程控制块(Thread Control Block, TCB) 也是在库里面来实现的,对于操作系统而言是看不到这个 TCB 的,它只能看到整个进程的 PCB。

所以,用户线程的整个线程管理和调度,操作系统是不直接参与的,而是由用户级线程库函数来完成线程的管理,包括线程的创建、终止、同步和调度等

用户级线程的模型,也就类似前面提到的多对一的关系,即多个用户线程对应同一个内核线程,如下图所示:
17
用户线程的优点:

  • 每个进程都需要有它私有的线程控制块(TCB)列表,用来跟踪记录它各个线程状态信息(PC、栈指针、寄存器),TCB 由用户级线程库函数来维护,可用于不支持线程技术的操作系统;

  • 用户线程的切换也是由线程库函数来完成的,无需用户态与内核态的切换,所以速度特别快;

用户线程的缺点:

  • 由于操作系统不参与线程的调度,如果一个线程发起了系统调用而阻塞,那进程所包含的用户线程都不能执行了。

  • 当一个线程开始运行后,除非它主动地交出 CPU 的使用权,否则它所在的进程当中的其他线程无法运行,因为用户态的线程没法打断当前运行中的线程,它没有这个特权,只有操作系统才有,但是用户线程不是由操作系统管理的。

  • 由于时间片分配给进程,故与其他进程比,在多线程执行时,每个线程得到的时间片较少,执行会比较慢;

以上,就是用户线程的优缺点了。

内核线程如何理解?存在什么优势和缺陷?

内核线程是由操作系统管理的,线程对应的 TCB 自然是放在操作系统里的,这样线程的创建、终止和管理都是由操作系统负责。

内核线程的模型,也就类似前面提到的一对一的关系,即一个用户线程对应一个内核线程,如下图所示:
18
内核线程的优点:

  • 在一个进程当中,如果某个内核线程发起系统调用而被阻塞,并不会影响其他内核线程的运行;

  • 分配给线程,多线程的进程获得更多的 CPU 运行时间;

内核线程的缺点:

  • 在支持内核线程的操作系统中,由内核来维护进程和线程的上下文信息,如 PCB 和 TCB;

  • 线程的创建、终止和切换都是通过系统调用的方式来进行,因此对于系统来说,系统开销比较大;

以上,就是内核线程的优缺点了。

轻量级进程如何理解?

轻量级进程(Light-weight process,LWP)是内核支持的用户线程,一个进程可有一个或多个 LWP,每个 LWP 是跟内核线程一对一映射的,也就是 LWP 都是由一个内核线程支持。

另外,LWP 只能由内核管理并像普通进程一样被调度,Linux 内核是支持 LWP 的典型例子。

在大多数系统中,LWP与普通进程的区别也在于它只有一个最小的执行上下文和调度程序所需的统计信息。一般来说,一个进程代表程序的一个实例,而 LWP 代表程序的执行线程,因为一个执行线程不像进程那样需要那么多状态信息,所以 LWP 也不带有这样的信息。

在 LWP 之上也是可以使用用户线程的,那么 LWP 与用户线程的对应关系就有三种:

  • 1 : 1,即一个 LWP 对应 一个用户线程;

  • N : 1,即一个 LWP 对应多个用户线程;

  • N : N,即多个 LMP 对应多个用户线程;

接下来针对上面这三种对应关系说明它们优缺点。先看下图的 LWP 模型:
19
1 : 1 模式

一个线程对应到一个 LWP 再对应到一个内核线程,如上图的进程 4,属于此模型。

  • 优点:实现并行,当一个 LWP 阻塞,不会影响其他 LWP;

  • 缺点:每一个用户线程,就产生一个内核线程,创建线程的开销较大。

N : 1 模式

多个用户线程对应一个 LWP 再对应一个内核线程,如上图的进程 2,线程管理是在用户空间完成的,此模式中用户的线程对操作系统不可见。

  • 优点:用户线程要开几个都没问题,且上下文切换发生用户空间,切换的效率较高;

  • 缺点:一个用户线程如果阻塞了,则整个进程都将会阻塞,另外在多核 CPU 中,是没办法充分利用 CPU 的。

M : N 模式

根据前面的两个模型混搭一起,就形成 M:N 模型,该模型提供了两级控制,首先多个用户线程对应到多个 LWP,LWP 再一一对应到内核线程,如上图的进程 3。

  • 优点:综合了前两种优点,大部分的线程上下文发生在用户空间,且多个线程又可以充分利用多核 CPU 的资源。

组合模式

如上图的进程 5,此进程结合 1:1 模型和 M:N 模型。开发人员可以针对不同的应用特点调节内核线程的数目来达到物理并行性和逻辑并行性的最佳方案。

2.6 调度

进程都希望自己能够占用 CPU 进行工作,那么这涉及到前面说过的进程上下文切换。

一旦操作系统把进程切换到运行状态,也就意味着该进程占用着 CPU 在执行,但是当操作系统把进程切换到其他状态时,那就不能在 CPU 中执行了,于是操作系统会选择下一个要运行的进程。

选择一个进程运行这一功能是在操作系统中完成的,通常称为调度程序(scheduler)

那到底什么时候调度进程,或以什么原则来调度进程呢?

2.7 调度时机

在进程的生命周期中,当进程从一个运行状态到另外一状态变化的时候,其实会触发一次调度

比如,以下状态的变化都会触发操作系统的调度:

  • 从就绪态 -> 运行态:当进程被创建时,会进入到就绪队列,操作系统会从就绪队列选择一个进程运行;

  • 从运行态 -> 阻塞态:当进程发生 I/O 事件而阻塞时,操作系统必须另外一个进程运行;

  • 从运行态 -> 结束态:当进程退出结束后,操作系统得从就绪队列选择另外一个进程运行;

因为,这些状态变化的时候,操作系统需要考虑是否要让新的进程给 CPU 运行,或者是否让当前进程从 CPU 上退出来而换另一个进程运行。

另外,如果硬件时钟提供某个频率的周期性中断,那么可以根据如何处理时钟中断,把调度算法分为两类:

  • 非抢占式调度算法挑选一个进程,然后让该进程运行直到被阻塞,或者直到该进程退出,才会调用另外一个进程,也就是说不会理时钟中断这个事情。

  • 抢占式调度算法挑选一个进程,然后让该进程只运行某段时间,如果在该时段结束时,该进程仍然在运行时,则会把它挂起,接着调度程序从就绪队列挑选另外一个进程。这种抢占式调度处理,需要在时间间隔的末端发生时钟中断,以便把 CPU 控制返回给调度程序进行调度,也就是常说的时间片机制。

2.8 调度原则

原则一:如果运行的程序,发生了 I/O 事件的请求,那 CPU 使用率必然会很低,因为此时进程在阻塞等待硬盘的数据返回。这样的过程,势必会造成 CPU 突然的空闲。所以,为了提高 CPU 利用率,在这种发送 I/O 事件致使 CPU 空闲的情况下,调度程序需要从就绪队列中选择一个进程来运行

原则二:有的程序执行某个任务花费的时间会比较长,如果这个程序一直占用着 CPU,会造成系统吞吐量(CPU 在单位时间内完成的进程数量)的降低。所以,要提高系统的吞吐率,调度程序要权衡长任务和短任务进程的运行完成数量

原则三:从进程开始到结束的过程中,实际上是包含两个时间,分别是进程运行时间和进程等待时间,这两个时间总和就称为周转时间。进程的周转时间越小越好,如果进程的等待时间很长而运行时间很短,那周转时间就很长,这不是我们所期望的,调度程序应该避免这种情况发生。

原则四:处于就绪队列的进程,也不能等太久,当然希望这个等待的时间越短越好,这样可以使得进程更快的在 CPU 中执行。所以,就绪队列中进程的等待时间也是调度程序所需要考虑的原则

原则五:对于鼠标、键盘这种交互式比较强的应用,我们当然希望它的响应时间越快越好,否则就会影响用户体验了。所以,对于交互式比较强的应用,响应时间也是调度程序需要考虑的原则
20
针对上面的五种调度原则,总结成如下:

  • CPU 利用率:调度程序应确保 CPU 是始终匆忙的状态,这可提高 CPU 的利用率;

  • 系统吞吐量:吞吐量表示的是单位时间内 CPU 完成进程的数量,长作业的进程会占用较长的 CPU 资源,因此会降低吞吐量,相反,短作业的进程会提升系统吞吐量;

  • 周转时间:周转时间是进程运行和阻塞时间总和,一个进程的周转时间越小越好;

  • 等待时间:这个等待时间不是阻塞状态的时间,而是进程处于就绪队列的时间,等待的时间越长,用户越不满意;

  • 响应时间:用户提交请求到系统第一次产生响应所花费的时间,在交互式系统中,响应时间是衡量调度算法好坏的主要标准。

说白了,这么多调度原则,目的就是要使得进程 要「快」

调度算法

不同的调度算法适用的场景也是不同的。

接下来,说说在单核 CPU 系统中常见的调度算法。

01 先来先服务调度算法

最简单的一个调度算法,就是非抢占式的先来先服务(First Come First Severd, FCFS)算法了。
21
顾名思义,先来后到,每次从就绪队列选择最先进入队列的进程,然后一直运行,直到进程退出或被阻塞,才会继续从队列中选择第一个进程接着运行

这似乎很公平,但是当一个长作业先运行了,那么后面的短作业等待的时间就会很长,不利于短作业。

FCFS 对长作业有利,适用于 CPU 繁忙型作业的系统,而不适用于 I/O 繁忙型作业的系统。

02 最短作业优先调度算法

最短作业优先(Shortest Job First, SJF)调度算法同样也是顾名思义,它会优先选择运行时间最短的进程来运行,这有助于提高系统的吞吐量。
22
这显然对长作业不利,很容易造成一种极端现象。

比如,一个长作业在就绪队列等待运行,而这个就绪队列有非常多的短作业,那么就会使得长作业不断的往后推,周转时间变长,致使长作业长期不会被运行。

03 高响应比优先调度算法

前面的「先来先服务调度算法」和「最短作业优先调度算法」都没有很好的权衡短作业和长作业。

那么,高响应比优先 (Highest Response Ratio Next, HRRN)调度算法主要是权衡了短作业和长作业。

每次进行进程调度时,先计算「响应比优先级」,然后把「响应比优先级」最高的进程投入运行,「响应比优先级」的计算公式:
23
从上面的公式,可以发现:

  • 如果两个进程的「等待时间」相同时,「要求的服务时间」越短,「响应比」就越高,这样短作业的进程容易被选中运行;

  • 如果两个进程「要求的服务时间」相同时,「等待时间」越长,「响应比」就越高,这就兼顾到了长作业进程,因为进程的响应比可以随时间等待的增加而提高,当其等待时间足够长时,其响应比便可以升到很高,从而获得运行的机会;

04 时间片轮转调度算法

最古老、最简单、最公平且使用最广的算法就是时间片轮转(Round Robin, RR)调度算法
24
每个进程被分配一个时间段,称为时间片(Quantum),即允许该进程在该时间段中运行

  • 如果时间片用完,进程还在运行,那么将会把此进程从 CPU 释放出来,并把 CPU 分配另外一个进程;

  • 如果该进程在时间片结束前阻塞或结束,则 CPU 立即进行切换;

另外,时间片的长度就是一个很关键的点:

  • 如果时间片设得太短会导致过多的进程上下文切换,降低了 CPU 效率;

  • 如果设得太长又可能引起对短作业进程的响应时间变长。将

通常时间片设为 20ms~50ms 通常是一个比较合理的折中值。

05 最高优先级调度算法

前面的「时间片轮转算法」做了个假设,即让所有的进程同等重要,也不偏袒谁,大家的运行时间都一样。

但是,对于多用户计算机系统就有不同的看法了,它们希望调度是有优先级的,即希望调度程序能从就绪队列中选择最高优先级的进程进行运行,这称为最高优先级(Highest Priority First,HPF)调度算法

进程的优先级可以分为,静态优先级或动态优先级:

  • 静态优先级:创建进程时候,就已经确定了优先级了,然后整个运行时间优先级都不会变化;

  • 动态优先级:根据进程的动态变化调整优先级,比如如果进程运行时间增加,则降低其优先级,如果进程等待时间(就绪队列的等待时间)增加,则升高其优先级,也就是随着时间的推移增加等待进程的优先级。

该算法也有两种处理优先级高的方法,非抢占式和抢占式:

  • 非抢占式:当就绪队列中出现优先级高的进程,运行完当前进程,再选择优先级高的进程。

  • 抢占式:当就绪队列中出现优先级高的进程,当前进程挂起,调度优先级高的进程运行。

但是依然有缺点,可能会导致低优先级的进程永远不会运行。

06 多级反馈队列调度算法

多级反馈队列(Multilevel Feedback Queue)调度算法是「时间片轮转算法」和「最高优先级算法」的综合和发展。

顾名思义:

  • 「多级」表示有多个队列,每个队列优先级从高到低,同时优先级越高时间片越短。

  • 「反馈」表示如果有新的进程加入优先级高的队列时,立刻停止当前正在运行的进程,转而去运行优先级高的队列;

25
来看看,它是如何工作的:

  • 设置了多个队列,赋予每个队列不同的优先级,每个队列优先级从高到低,同时优先级越高时间片越短;

  • 新的进程会被放入到第一级队列的末尾,按先来先服务的原则排队等待被调度,如果在第一级队列规定的时间片没运行完成,则将其转入到第二级队列的末尾,以此类推,直至完成;

  • 当较高优先级的队列为空,才调度较低优先级的队列中的进程运行。如果进程运行时,有新进程进入较高优先级的队列,则停止当前运行的进程并将其移入到原队列末尾,接着让较高优先级的进程运行;

可以发现,对于短作业可能可以在第一级队列很快被处理完。对于长作业,如果在第一级队列处理不完,可以移入下次队列等待被执行,虽然等待的时间变长了,但是运行时间也会更长了,所以该算法很好的兼顾了长短作业,同时有较好的响应时间。

下面通过一个银行业务办理的案例来帮助大家理解上面的这些调度算法:

办理业务的客户相当于进程,银行窗口工作人员相当于 CPU

现在,假设这个银行只有一个窗口(单核 CPU ),那么工作人员一次只能处理一个业务。
26
那么最简单的处理方式,就是先来的先处理,后面来的就乖乖排队,这就是先来先服务(FCFS)调度算法。但是万一先来的这位老哥是来贷款的,这一谈就好几个小时,一直占用着窗口,这样后面的人只能干等,或许后面的人只是想简单的取个钱,几分钟就能搞定,却因为前面老哥办长业务而要等几个小时,你说气不气人?
27
有客户抱怨了,那我们就要改进,我们干脆优先给那些几分钟就能搞定的人办理业务,这就是短作业优先(SJF)调度算法。听起来不错,但是依然还是有个极端情况,万一办理短业务的人非常的多,这会导致长业务的人一直得不到服务,万一这个长业务是个大客户,那不就捡了芝麻丢了西瓜。
28
那就公平起见,现在窗口工作人员规定,每个人我只处理 10 分钟。如果 10 分钟之内处理完,就马上换下一个人。如果没处理完,依然换下一个人,但是客户自己得记住办理到哪个步骤了。这个也就是时间片轮转(RR)调度算法。但是如果时间片设置过短,那么就会造成大量的上下文切换,增大了系统开销。如果时间片过长,相当于退化成退化成 FCFS 算法了。
29
既然公平也可能存在问题,那银行就对客户分等级,分为普通客户、VIP 客户、SVIP 客户。只要高优先级的客户一来,就第一时间处理这个客户,这就是最高优先级(HPF)调度算法。但依然也会有极端的问题,万一当天来的全是高级客户,那普通客户不是没有被服务的机会,不把普通客户当人是吗?那我们把优先级改成动态的,如果客户办理业务时间增加,则降低其优先级,如果客户等待时间增加,则升高其优先级。
30
那有没有兼顾到公平和效率的方式呢?这里介绍一种算法,考虑的还算充分的,多级反馈队列(MFQ)调度算法,它是时间片轮转算法和优先级算法的综合和发展。它的工作方式:
31

  • 银行设置了多个排队(就绪)队列,每个队列都有不同的优先级,各个队列优先级从高到低,同时每个队列执行时间片的长度也不同,优先级越高的时间片越短

  • 新客户(进程)来了,先进入第一级队列的末尾,按先来先服务原则排队等待被叫号(运行)。如果时间片用完客户的业务还没办理完成,则让客户进入到下一级队列的末尾,以此类推,直至客户业务办理完成。

  • 当第一级队列没人排队时,就会叫号二级队列的客户。如果客户办理业务过程中,有新的客户加入到较高优先级的队列,那么此时办理中的客户需要停止办理,回到原队列的末尾等待再次叫号,因为要把窗口让给刚进入较高优先级队列的客户。

可以发现,对于要办理短业务的客户来说,可以很快的轮到并解决。对于要办理长业务的客户,一下子解决不了,就可以放到下一个队列,虽然等待的时间稍微变长了,但是轮到自己的办理时间也变长了,也可以接受,不会造成极端的现象,可以说是综合上面几种算法的优点。

本文出处

本文转载自小林coding 如下文章:
()[https://mp.weixin.qq.com/s?__biz=MzA4MjEyNTA5Mw==&mid=2652572249&idx=1&sn=2a9ca2c07e62a34de53d5e2393211ca9&chksm=84652213b312ab05aca2880e8dcab311a43449b0d779a5e2676c1843ee8a0b6103c0c20e3fd3&scene=0&xtrack=1&key=91d26c6f1e2e414838aef8aef6f22cbe8fca88fea19c8596385b3c4039d82ee0e7a465541a30923effee6e2cd9fae1f3d1a6f2394471d973da365b6881b88629ee73b181d6cc0245b2751fb4a6422b68cae59867c4882401b1f20d879f80c6b4b2676582ca8dee10df7976620cd6fd116b6c676e06f3a49f0988646b9d487d27&ascene=14&uin=MTYxNDY5NzEwMA%3D%3D&devicetype=Windows+10+x64&version=6209051a&lang=zh_CN&exportkey=ARa47iNCOEjgiBS1e37MIio%3D&pass_ticket=ILXvaP9J7C49mrTt3miy1i%2BXphXPVX3D2Covw%2Fmko0g5HRGpUs94UlFjRWXAdjV2&wx_header=0#]

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. adb 拉取指定大小,类型的文件

    https://blog.csdn.net/babytiger/article/details/108468363上回说到如何拉取文件,但是要拉取指定文件夹下,指定大小的所有jpg文件,如果目录不多还好,一个一个拉,但是如果文件夹很多,名字我也不知道,怎么办?写个脚本就可以了pull_all.bat@echo off setlocal enabledel…...

    2024/4/16 18:04:02
  2. Java面试题:快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?

    Java面试题 文章目录Java面试题一、快速失败二、安全失败提示一、快速失败 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加、删除、修改),则会抛出Concurrent Modification Exception。 原理:迭代器在遍历时直接访问集合中的内容,并且在遍…...

    2024/4/13 0:41:49
  3. 下载三调举证照片

    下载三调举证照片前言一、软件介绍1、系统要求2、软件UI3、下载方式二、使用步骤1、打开软件2、选择下载方式3、选择保存目录4、点击“下载举证照片”5、举证照片存放目录说明三、下载地址前言 三调外业通过举证平台拍照举证,因保密要求内业修改数据不能直接接外网查看举证。s…...

    2024/3/22 1:38:44
  4. 入职字节跳动那一天,我哭了(蘑菇街被裁,奋战7个月拿下offer)

    前言先说一下自己的个人情况,18届应届生,通过校招进入到了蘑菇街,然后一待就待了差不多2年多的时间,可惜的是今年4月份受疫情影响遇到了大裁员,而我也是其中一员。好在早有预感,提前做了准备,之前一直想去字节跳动,年前就已经在做准备了,这场持久战拉得很长,也最终以…...

    2024/4/13 14:27:30
  5. 十年游戏建模师给想学次世代游戏建模同学的一些忠告,太受益了

    很多初学者总是在学习建模的时候遇到绊子,但是又不知道哎怎么解决,然后通过日常和小伙伴聊天发现了在初学者身上容易出现的几个问题:一是对工具的使用还不够熟练,有些工具都不知道是干嘛用的,二是对布线的规范没有太大的了解,三是对建模制作流程不清晰和板绘下的功力不够,…...

    2024/4/13 13:26:46
  6. Delphi 开发的基于 Indy 的 WebBroker 或者 WebService 服务器支持 https

    用基于 Indy HTTPServer 的内置 Web 服务器的独立运行模式,基于 WebBroker 架构,开发简单的 WebServer 应用,如果访问量不大,是非常简单轻松调试方便的模式。开发 WebService 服务器端,也同样可以采用 Stand-alone 模式,一个独立运行的 EXE 程序,内置了一个 Web 服务器,…...

    2024/4/13 18:18:59
  7. 电力电子建模和仿真的专用模块库

    SimPowerSystems 库是在Simulink仿真平台进行电力、电力电子建模和仿真的专用模块库。元器件的模型都用框图来表示,该库的基本模块按顺序有八个部分。 (1)应用子库。包含“分布式电源库”、“特种电机库”和“柔性交流输电系统库”三个子库。 (2)电源子库。能提供交直流电…...

    2024/4/12 21:30:10
  8. python 翻译模块 翻译API使用(百度、有道、谷歌)

    1、翻译模块、api使用分析 1、translate库:使用简单,但是有次数限制,翻译的准确性中等; 2、百度api(推荐使用): 代码简单,有模块,但是需要注册,获取key值,翻译的准确性中下; 3、chrome翻译api:代码复杂,次数限制, 但是翻译的准确性较高; 4、有道翻译:代码复杂…...

    2024/4/13 18:55:04
  9. elasticsearch详解

    生活中的数据 搜索引擎是对数据的检索,所以我们先从生活中的数据说起。我们生活中的数据总体分为两种:结构化数据 非结构化数据**结构化数据:**也称作行数据,是由二维表结构来逻辑表达和实现的数据,严格地遵循数据格式与长度规范,主要通过关系型数据库进行存储和管理。指…...

    2024/4/13 9:48:05
  10. 模型可解释性-LIME

    在算法建模过程中,我们一般会用测试集的准确率与召回率衡量一个模型的好坏,但在和客户的实际沟通时,单单抛出一个数字就想要客户信任我们,那肯定是不够的,这就要求我们摆出规则,解释模型。但不是所有的模型都是规则模型,一些黑盒模型(比如神经网络)有着更高的准确率,…...

    2024/4/13 20:40:43
  11. BugKu Web篇通关wp

    BugKu Web篇通关wp 文章目录BugKu Web篇通关wp0x01 WEB20x02 计算器0x03 web基础$_GET0x04 web基础$_POST0x04 矛盾0x05 WEB30x06 域名解析0x07 你必须让他停下0x08 本地包含0x09 变量10x10 WEB50x11 头等舱0x12 网站被黑0x13 管理员系统0x14 web40x15 flag在index里0x16 输入密…...

    2024/4/13 19:22:56
  12. Netty的网络编程模型

    网络编程模型传统的BIO网络编程模型(线程池)Netty的网络编程模型按照场景去理解NettyJDK原生的NIO编程Netty在原生NIO编程的改进 传统的BIO网络编程模型(线程池) 传统的网络编程模型,以Tomcat为代表,服务端的ServerSocketChannel个数取决于线程池中线程的数量,如图所示。…...

    2024/4/13 1:06:02
  13. [Java]学习笔记18:使用对象类型作为方法的参数和返回值

    对象类型作为方法的参数 当一个对象作为参数,传递到方法当中时,实际上传递进去的是对象的地址值。Demo03PhoneParam.java package cn.edu.qilu.day1.demo07;public class Demo03PhoneParam {public static void main(String[] args) {Phone one = new Phone();one.brand = &q…...

    2024/4/13 8:50:17
  14. C#网络编程(1)

    ◆IP协议:网际协议(Internet Protocol) ◆TCP协议: 传输控制协议(Transmission Control Protocol) ◆UDP协议:用户数据协议(User Datagram Protocol) ◆IPX/SPX协议:互联网包交换协议-IPX,顺序分组交换协议-SPX ◆ATM协议:异步传输模式协议Microsoft. Net Framework为应用程序…...

    2024/4/13 0:18:01
  15. 5G 与 MEC 边缘计算

    转自(JmilkFan_范桂飓)目录文章目录目录前言参考文献通信网络核心网演进之路早古时期2G 网络架构3G 网络架构4G 网络架构5G5G 网络的需求5G 网络架构的设计原则5G 网络的逻辑架构5G 核心网络的关键技术SBA 基于服务的架构微服务化基于服务的接口CUPS 控制与用户面分离网络切片…...

    2024/4/13 9:46:23
  16. 详解一条查询select语句和更新update语句的执行流程

    前言一条select语句的执行流程建立连接查询缓存解析器和预处理器词法解析和语法解析(Parser)预处理器(Preprocessor)查询优化器(Query Optimizer)优化器可以做哪些优化优化器并不是万能的优化器如何得到查询计划存储引擎查询返回结果一条update语句的执行流程Buffer Poolredo l…...

    2024/4/13 14:40:04
  17. HTTPS,HTTP追加协议 - 重学计算机网络系列(4)

    前言本篇文章主要讲HTTPS,HTTP和HTTPS区别,认证,SPDY的AJAX与Comet,WebsocketHTTPS HTTP的缺点 通信使用明文可能会被窃听 由于HTTP本身不具备加密的功能,所以也无法做到对通信整体(使用HTTP协议通信的请求和响应的内容)进行加密。即,HTTP报文使用明文(指未经过加密的…...

    2024/4/13 17:30:50
  18. 常见的Web攻击及防御办法 - 重学计算机网络系列(5)

    Web攻击分类 简单的HTTP协议本身并不存在安全性问题,因此协议本身几乎不会成为攻击的对象。应用HTTP协议的服务器和客户端,以及运行在服务器上的Web应用等资源才是攻击目标。 web应用的攻击模式有以下两种主动攻击(主要攻击服务器上的资源)SQL注入攻击 OS命令注入攻击 其他被…...

    2024/4/13 15:10:54
  19. 浏览器系列(上)- 前端发展历史,渲染进程

    前端发展历史 早期时代(1990-)Web 1.0 时代,非常适合创业型小项目,不分前后端,经常 3-5 人搞定所有开发。页面由 JSP、PHP 等工程师在服务端生成,浏览器负责展现。基本上是服务端给什么浏览器就展现什么,展现的控制在 Web Server 层。 这种模式的好处是简单明快,适合小…...

    2024/4/13 17:31:40
  20. 浏览器系列(中) - 浏览器缓存,WebStorage

    缓存定义缓存是一种保存资源副本并在下次请求时直接使用该副本的技术。从一次完整的HTTP请求看缓存分类客户端缓存存在于客户端本地,如果客户端命中缓存,甚至不需要发起HTTP请求,相当于直接在本地拿数据。一般在这里的缓存技术有Cookie,localstorage,sessionstorage,本地文件…...

    2024/4/13 8:10:02

最新文章

  1. 算法和数据结构简介

    文章目录 算法的分类硬计算类算法软计算类算法 数据结构分类(宏观)连续结构跳转结构 链表按值传递,按引用传递单链表和双链表链表反转需求实现代码 合并两个有序链表需求 实现代码 算法的分类 硬计算类算法 精确求解,但是某些问题都是使用硬计算类的算法…...

    2024/4/19 1:39:52
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. STL--vector有哪些应用场景

    vector 在 C 中是一种非常灵活和强大的容器,适用于多种不同的应用场景。以下是一些常见的应用场景: 1 动态数据集合:当你不确定数据集的大小,或者数据集的大小会随时间变化时,vector 是理想的选择。例如,在…...

    2024/4/16 4:46:05
  4. Vue ts 如何给 props 中的变量指定特定类型,比如 Interface 类的

    Vue ts 如何给 props 中的变量指定特定类型,比如 Interface 类的 我有一个这样的变量值类型 一、在没用 ts 之前的 props 类型指定方式 我们都知道之前在没用 ts 之前的 props 变量值类型指定方式: 如下图,billFood 定义方式是这样的&…...

    2024/4/18 16:27:07
  5. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义:dp[i][j]表示当背包容量为j,用前i个物品是否正好可以将背包填满&#xff…...

    2024/4/18 18:47:03
  6. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/4/18 8:11:38
  7. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon,直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件,我们讨论Spring负载均衡以Spring Cloud2020之后版本为主,学习Spring Cloud LoadBalance,暂不讨论Ribbon…...

    2024/4/18 8:11:47
  8. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中,周界防范意义重大,对园区的安全起到重要的作用。常规的安防方式是采用人员巡查,人力投入成本大而且效率低。周界一旦被破坏或入侵,会影响园区人员和资产安全,…...

    2024/4/18 8:11:56
  9. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时,常要分析网页Html,例如网页在加载数据时,常会显示“系统处理中,请稍候..”,我们需要在数据加载完成后才能继续下一步操作,如何抓取这个信息的网页html元素变化&…...

    2024/4/17 23:48:57
  10. 【Objective-C】Objective-C汇总

    方法定义 参考:https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/4/19 1:39:20
  11. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    👨‍💻博客主页:花无缺 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】🌏题目描述🌏输入格…...

    2024/4/18 8:12:27
  12. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/4/18 17:23:55
  13. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕,各大品牌纷纷晒出优异的成绩单,摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称,在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁,多个平台数据都表现出极度异常…...

    2024/4/18 23:06:50
  14. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令,这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/4/18 21:25:02
  15. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b,我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边, b b b 同理,则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/4/18 18:47:03
  16. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息,并安装一些有助于配置官方 NGINX 软件包仓库的软件包: apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/4/18 15:01:51
  17. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限(ROW FORMAT)配置标准HQL为: ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/4/18 3:18:41
  18. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中,传感器和控制器产生大量周…...

    2024/4/18 12:50:28
  19. --max-old-space-size=8192报错

    vue项目运行时,如果经常运行慢,崩溃停止服务,报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中,通过JavaScript使用内存时只能使用部分内存(64位系统&…...

    2024/4/18 21:24:56
  20. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞,例如可以被劫持的合法软件(例如浏览器或 Web 应用程序插件)中的错误。 恶意软件渗透可能会造成灾难性的后果,包括数据被盗、勒索或网…...

    2024/4/18 8:47:13
  21. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧! 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,所以我们也称为原型对象…...

    2024/4/18 21:24:54
  22. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错,但存在一个缺陷:无法禁止通过实例化多个对象来创建多名总统: President One, Two, Three; 由于复制构造函数是私有的,其中每个对象都是不可复制的,但您的目…...

    2024/4/18 8:12:50
  23. python django 小程序图书借阅源码

    开发工具: PyCharm,mysql5.7,微信开发者工具 技术说明: python django html 小程序 功能介绍: 用户端: 登录注册(含授权登录) 首页显示搜索图书,轮播图&#xff0…...

    2024/4/18 18:47:01
  24. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/4/18 0:24:11
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57