轮询、中断、优先级、阻塞、异步

1409 2022-05-04 09:56

又到了老村长喜欢编故事的环节,今天讲一个人老心不老的故事。中国老龄化越来越严重了。一堆老头老太太们晒着太阳,遛着大街,但还是免不了郁闷。总觉得自己的大时代已经过去了,气血郁结。久则生病。于是我开了一个养老院。提供优美的环境和整洁舒适的住宿餐饮。但是招收的都是依然抱有希望和理想的老同志。招来的这些人我很满意。他们都想有点儿事儿做,觉得有组织有纪律有事做比什么都重要。但是他们有些缺点是不可避免的。那就是在习惯了40年的工龄工作之后,他们忍不住的要干活。干什么都无所谓。但是岁月积淀了太多的故事,让他们很散漫,闲着没事就会聊天唠嗑。他们很矛盾,知道来这里是要付出劳动的,但是同时又迷茫到不屑于付出换来的回报。就是想干活,但是又没有毅力。我想了想,管理他们的人肯定不能从他们当中挑选,于是我又招了一些年轻人。年轻人可真是五花八门。有干活特利索,但是没什么想法的人,他们的信念就是劳动创造一切,干就完了。我称之为急性子。有考虑特别周全的,要求每一个细节都完美,他们有追求所以有计划。但是计划中每一环都很周全,所以考虑得多,干得就慢。我称之为慢性子。还有很少的一部分年轻人,他们有脑子,有力气,效率高。我称他们为核心。但是他们要价很贵。于是,我根据他们的性格特点、能力水准、价钱酬劳,招了一小撮,用于管理,或者说组织。那一大堆老头老太太。随着分工合作以及流水线的设计。我让核心(cpu)来做绩效考核。他们人数最少,但他们所到之处。一定是干劲儿十足、热火朝天的老头老太太们。似乎他们就是领导视察(轮询)。那帮精明的老家伙们很清楚,看不见的工作就是白努力。但是这些cpu年轻人太少了,而且他们出场费太贵了,所以我让那些相对便宜的急性子,带着cpu的袖标,去做跑腿工作。然后让cpu去交接急性子具体的工作安排。于是cpu们就可以三班倒地坐在窗口等待急性子们的消息了。cpu们得到了良好的休息。出场费也降下来了。但是急性子们太累了,他们要监视没一个老头老太太的工作数据。他们很听话,但是他们没脑子,不记事儿。看到了一个老头或者老太太的作息,就回来报道。这让他们很累。于是我派出慢性子常驻在老头老太太们工作的包间里。并且包间也根据老头老太太们的意愿。划分了折纸盒包间、印花包间、写产品投送地址包间等等包间。每个包间都只做他们愿意或者擅长的事情。慢性子将他们负责的包间里所有老头老太太的工作数据记录好,让急性子带给cpu去做绩效核算。不久后我发现,cpu与急性子之间的交接可以更加有规律。没必要让cpu面对面的与急性子交流,给急性子们预备一个表格,每次来cpu大厅交接的时候只需要把自己要交接的话写在表格里就好了。cpu每个时间片(单位时间段)打开窗口取进去一堆报表处理就好了。但是总有一些老头老太太们干着干着就生病了,需要紧急调剂,那么计算、安排、配给就需要cpu付出额外的精力。于是我给这类事件优先处理的要求。为了有优先级,就增加了cpu每次指令周期(注意时间片内是可以做很多条指令的。时间片的计数基础单位是计算机时钟体系,和这里的指令周期没有必然联系,一条指令周期包括单机器周期、双机器周期、四机器周期,前两者用于单字节和双字节指令,三字节指令都是双机器周期,只有乘、除指令占用4个机器周期。机器周期,CPU访问一次内存所花的时间较长,因此用从内存读取一条指令字的最短时间来定义。机器周期也称为CPU周期。在计算机中,为了便于管理,常把一条指令的执行过程划分为若干个阶段(如取指、译码、执行等),每一阶段完成一个基本操作。完成一个基本操作所需要的时间称为机器周期。)的时候,看一眼交接大厅红灯的习惯(我们称之为中断),cpu于是成了一个有限状态机。(CPU周期)除了Fetch(从内存中读取指令)、Decode(解释指令)、Execute(执行指令)之外,还要Interrupt(检测中断)。后来,cpu除了忙活这一帮老头老太太们的工资之外,还要对接外面的物流、成本、需求、设计、销售、越做越大的同时,我将cpu的做工资工作划立出了财务工作。cpu每个月派其中一个人去干几天就好了。而急性子们也不用把信息填写到cpu大厅的报表中了,直接去cpu大厅的小隔间,财务办公室,写到财务数据库里就好了。这样避免了cpu每次取了急性子的数据还要写入数据库的工作。(DMA方式产生)。再后来,为了急性子们不排队,我给他们到财务室建立了专门的通道。(通道控制方式产生)。至此,我们讲明白了,cpu指令周期(中断)-》cpu时间片轮转(调度算法)-》优先级(调度算法)-》I/O控制方式(轮询、中断、DMA、通道控制)来解决资源利用和速度快慢的问题。那么接下来就是有意思的阻塞和异步问题了。有了外脑,相对于cpu的I/O(外设)。当外设有了些脑子,可以直接给cpu取用的数据库(内存)直接写数据的功能之后。比如网卡。也就是刚才说的慢性子们真的有脑子,那么利用他们的脑子直接给cpu取用的地方写数据了。那么慢性子就可以利用中断机制来告诉cpu。喂,我这个完美的盒子满了,你可以取用了。而不通过急性子去唤醒cpu。(cpu要是被急性子骚扰,那还不打屎他)。cpu这么高傲的人,但是乖乖的听了慢性子的话。那么多个慢性子,当cpu发现慢性子在写作业的时候,cpu看一眼就走,绝不停留,这就是慢性子阻塞了。但是并不消耗cpu。当慢性子抬头的时候,cpu才会正眼对待慢性子手上的那份工作。我们把cpu(服务端)盯着慢性子(客户端)写作业叫做同步阻塞、我们把cpu每过几分钟就回来看看慢性子有没有写完作业叫做同步非阻塞(服务端解放)、慢性子买了个铃铛,想告诉cpu你可以忙去了,但是cpu闲的蛋疼就要看着慢性子写作业,慢性子写了一会儿,被告知可以去喝茶可以上厕所,但是cpu必需要搞定这一单,否则没法抽身,叫异步(客户端解放)阻塞(服务端不解放)。慢性子和cpu约定好了,写完作业就敲铃,敲铃cpu就来收作业,叫异步非阻塞。

 

这四个槪念两两组合,会形成4个新的槪念,如下:
1.同步阻塞:客户揣发送请求给服务揣,此时服务端处理任务时间很久,则客户端则被服务端堵塞了,所以客户端会一直等待服务端的响应,此时客户端不能做其他任何事,服务端也不接受其他客户揣的请求。这种通信机制比较简单租暴,但是效率不高。


2.同步非阻塞:客户端发送请求给服务端,此时服务端处理任务时间很久,这个时候虽然客户端会一直等待响应,但是服务端可以处理其他的请求,过一会回来处理原先的。这种方式很高效,一个服务端可以处理很多请求,不会在因为任务没有处理完而堵着,所以这是非阻塞的。


3.异步阻塞:客户揣发送请求给服务端,此时服务端处理任务时间很久,但是客户端不会等待服务器响应,它可以做其他的任务,等服务器处理完毕后再把结果响应给客户端,客户端得到回调后再处理服务端的响应。这种方式可以避免客户端一直处于等待的状态,优化了用户体验,其实就是类似于网页里发起的ajax异步请求。


4.异步非阻塞:客户端发送请求给服务端,此时服务端处理任务时间很久,这个时候的任务虽然处理时间会很久,但是客户端可以做其他的任务,因为他是异步的,可以在回调函数里处理响应;同时服务端是非阻塞的,所以服务端可以去处理其他的任务,如此,这个模式就显得非常的高效了 。

以上厕所为例:
•同步就是我需要自己每隔一段时间,以轮训的方式去看看有没有空的坑位;
•异步则是有人拉完茅坑会通知你,通知你后你再回去蹲;
•阻塞就是在等待的过程中,你不去做其他任何事情,干等着;
•非阻塞就是你在等待的过程中可以去做其他的事,比如抽烟、喝酒、烫头、玩手机。


小结:异步的优点显而易见,大大优化用户体验,非阻塞使得系统资源开销远远小于阻塞模式,因为系统不需要创建新的进程或线程,大大地节省了系统的资源,如此多出来的系统资源可以给其他的中间件去服务了。

 

从小到大来说:时钟周期,CPU周期,指令周期,CPU时间片

时钟周期:一个脉冲需要的时间,频率的倒数

CPU周期:读取一个指令节所需的时间

指令周期:读取并执行完一个指令所需的时间

CPU时间片:CPU分给每个进程的时间

时钟周期:这个名字的英文clock cycle; clock period;时钟是用来计时的,是一个基本单位;在计算机中,cpu的晶振时间就是一个最最基本的单位,因此时钟周期很基本,别的周期都用它来参考。
CPU周期 :又称机器周期,CPU访问一次内存所花的时间较长,因此用从内存读取一条指令字的最短时间来定义。它一般由12个时钟周期(振荡周期)组成,也是由6个状态周期组成。而振荡周期=1秒/晶振频率,因此单片机的机器周期=12秒/晶振频率 。
总线周期(BUS Cycle):也就是一个访存储器或I/O端口操作所用的时间。
 
指令周期简介
CPU每取出一条指令并执行这条指令,都要完成一系列的操作,这一系列操作所需要的时间通常叫做一个指令周期。换言之指令周期是取出一条指令并执行这条指令的时间。由于各条指令的操作功能不同,因此各种指令的指令周期是不尽相同的。例如一条加法指令的指令周期同一条乘法指令的指令周期是不相同的。 指令周期常常用若干个CPU周期数来表示,CPU周期也称机器周期。指令不同,所需的机器周期数也不同。对于一些简单的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令。 [1]  指令占用周期主要与指令的操作功能有关。有以下特点:
1、指令不同,所需的机器周期数也不同。对于一些简单的的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。
2、从指令的执行速度看,单字节和双字节指令一般为单机器周期和双机器周期,三字节指令都是双机器周期,只有乘、除指令占用4个机器周期。因此在进行编程时,在完成相同工作的情况下,选用占用机器周期少的命令会提高程序的执行速率,尤其是在编写大型程序程序的时候,其效果更加明显。
 
关于时间大小。
我们买计算机、手机都知道买cpu频率更高的,代表速度更快。实际上就是时钟周期越短。频率的倒数就是周期,所以频率越高,时钟周期越小,代表在一个时钟周期内,CPU仅完成一个最基本的动作消耗的时间越短,这里通常用CPU去内存中读取一个指令字的最短时间来规定CPU周期(机械周期),一个机械周期包含多个时钟周期。而指令周期包括多个机械周期。一条指令的基本操作包括:取值、译码、执行、中断等。一条指令周期包括单机器周期、双机器周期、四机器周期,前两者用于单字节和双字节指令,三字节指令都是双机器周期,只有乘、除指令占用4个机器周期。而cpu这种金贵的资源要充分使用,就需要三班倒累死他,所以我们把一个任务(一个进程)能分到的cpu时间,称为占用了多少个时间片,时间片划分的大小,代表了能容纳执行多少条指令,这里不详细分析。一次做的很多,如果遇到阻塞,就会耽误更多的时间,一次做的很少,那么来回切换就会浪费记忆和恢复的时间。但是一个进程的指令一定是大过一个时间片,才会有并行的感觉。否则就变成单进程工作了,流水线的优势就在于通道的多部分互相错位叠加。然后并行出来一堆的结果。可以看到,中断的地位是在指令周期。比时间片还要细腻。而阻塞,则是阻塞在时间片的交替上。同步和异步是客户端的选择,已经不再服务端的cpu考虑范畴里了。分清了这些。才可以去设计高并发、分布式、多线程的应用场景。

全部评论

·