00:00
程序写完了,我们来看一下前面写的这个程序,跟我们这一个分析的ni模型,它是不是能够对应上。我们从几个方向来进行这个分析呢?首先我们先来看一下,就是boss group和worker group,它是怎么来确定它下面含有多少个。下面还有多少个子线程,或者说还有多少个IO loop的?那首先我们来分析这一个问题。一个个分析,打开我们的代码。对,那这个怎么分析呢?我们把先先关闭一下。关闭,我们下一个断点在这里,好吧,下一个断点在这里,待会儿我们可以看到,那首先我告这样子我们先做,我先做一个说明吧,我先做一个说明。就是boss,就是我们这个boss group。和worker group。
01:01
Work group。它含有的。含有的子线程。子线城。也就是含有的这个东西叫NIO。Loop。的个数。的个数。是怎么确定呢?是这样子的。呃。是默认,默认是你CPU的。这个核数就是你的有几核CPU核核数。和。合数乘以一个二,我们来看一下是不是这样的道理,我们随便找一个哈,往这里面追它的代码。追进去大家有没有看到,当你不填参数的时候,其实。它传入的是一个零,我们继续往里面追。
02:01
再往里面追。追。再追。是不是可以再再继续往里面追啊,追到这调用了super好追到它的负雷了,追到负雷大家有没有发现在这里。他说如果传进来的n stress等于零,它就会返回这个值,返回一个default event loop stress就是返回一个默认的事件循环线程的数量,那这个值到底是多大呢?我们进到这里面,大家会发现它其实是一个static性质的一个in特值。而这个值呢,是在。Static代码块进行初始化的,那这个值等于多少呢?大家有看到其实它是等于这个值。就这这个和这个求一个最大值,那大大家可以看到system,也就也就是他是这样子的,返回的是这个值。就是runtime valuable process这个这这个方法,它可以返回你当前机器的。
03:06
CPU的和有几核?然后乘以二。嗯,我大家可以看到老师的电脑上呢,它的盒,我我这有几盒呢,我是四盒。我们点一下哈。殿下适合。同学们看这边。是不是这是第一个。第二个,第三个。哎,你看我一共有123上面四。上面这两个不是啊,上面就是分别对两,呃,这个我是双CPU4核嘛,那么这是一个CPU,这个CPU一个CPU有两个核,所以说我一共有四核,那如果有四核的话呢,同学们可以知道,在我没有传参数的时候,其实其实我我创建的。Boss group里面有八个。也也就是说。
04:01
也就是这边我boss group里面有八个子线程及有八个IO event loop worker呢也有八个,我们来验证一下,验证一下。是不是这样子的啊,首先嗯。这这个方法返回的就是一个四,我们来验证一下。写一段代码。Test。做方法。System。输出我们先运行运行一下这段代码。它会返回四。它会返回一个四,的确如此,对不对?好的,明白这个道理过后呢,我们就更清晰的来看一下。Debug一下。往下看,Boss group和worker group往下走,走两步。再走一步,好,我们看boss group,那么boss boss group呢,我们往这儿点开,首先看到类型,它的类型是不是IO event lo group啊。
05:04
往下点开,往下一点开,你会发现它有char的子线程,那下面子线程呢,是不是有。几个呀?有八个,而且每一个子线程,它的类型是n IO lo。看清楚没有。哎,你看这里面有大量的东西是不是。没问题吧?这就证明的确在你默认情况下,呃,就是它会产生八个事件循环组,呃事件循环。有八个子线程,那同样道理,我们看worker group呢,对不对?Worker group也是一样的道理。看到没有也是八个,那么每一个呢,就是相当于说。Group下面有八个。事件循环及n IO event loop,而且大家有没有发现它返回的真实的类型,就是它是用哪个数据来管理的呢?用这个数组就是呃,类型为event exor来管理,也就是说呃,我们每一个n IO event loop呢?其实最终是靠这个event ex来进行这个。
06:12
这个这个调用或者是处理的。好,这一点大家要非常的清晰,非常的清晰,那现在呢,我们再来看一下,再来分析第二一个问题,什么问题呢?我想给大家分析一下。我们能不能指定呢?比如说我现在想指定它为。一个,而这边group呢,我想指定八个,也就是说boss group在一般情况下其实没有必要整那么多是吧?我们假设boss group,我们只需要一个event lo就可以了,这边八个,然后这边做完了之后,我们来用八个,我们这边产生八个client。我们来看一看,嗯,有,如果有八个client去进行这个服务器的数据的通讯的话,他这个worker group是怎么去分配他这八个IO event loop的,把它机制找一下好不好,我们再来看打开程序。
07:07
那现在呢,我指这个指定就是一。Boss group,我来一个一这边呢,有八个,有八个好,有八个过后我在哪里去输出这个现成的信息呢?我在这输出。是不是他每次,呃,就是当有一个客户端发送消息的时候,他会在China read这边进行一个读取,没问题吧。没问题,好,那现在呢,我在这里输出一下当前现成的信息。服务器。啊,读取读取线程。好读取限制呢,我这里用。点。current.g。也就是说,把当前他的现成的名字打出来,好,同学们,我们来玩一把。现在呢,我把这个先关闭好,关闭,关闭过后呢,我们来让一下。
08:00
跑起来哈。跑起来。好的。啊,跑起来过后呢,我们现在启动它的C端第一个来了。大家可以看到服务器这端呢,他说我第一个就是现在跟这个command兰,就是跟我第一个呢是。那这个线程接我们NL event group group下面的第一个,你认为你可以认为是我们工作线程下面的第一个子线程及第一个。这个东西线循环。那呃,现在我们再来运行第二个,现在你看他现在没有在读数据啊,因为你还没发呢,我们在发送第二个。第二个呢,大家可以猜测到它应该是用哪个线程的呢?是不是应该用三杠二了,是不是三杠二。也就是说跟我们第二个就是根据他这个分配机制,他把第二一个worker的就是这个worker group里面的第二一个n IO event lo这个线程分配给我们第二一个。
09:11
柯南,呃,柯南的端,那下面呢,我就快速跑了,这应该是第三个。是吧,再起一个,这是第四个。那服务器那边应该是对应的是第四个,呃,线程给他进行服务,这是第五一个。好,我们再来看第六一个。第六一个。再来第七个。第七个再来第八一个,好,我们先来看,现在呢,已经有八个线程啊,有八个客户端跟我们server来进行这个通讯,那么我们可以看到的确是这样子的,第一次三杠一,三杠二,三杠三,三杠四。三杠五。三杠六,三杠七,三杠八,那我现在想问的问题是,如果我们再来一个会怎么办呢?它会分配哪一个呢?好,我们来跑一个,再来第九一个,客南端第九一个它会怎么分配呢?打开这里我们发现第九一个它又反复的用第一个了,也就是说你可以认为在默认的情况下呢,我们这个worker group。
10:16
Worker group里面如果有八个。呃,如果我有,我有八个这个循环事,循环事件。就是event loop,那么你这边客户端按照顺序来,第一个呢,我就分配给你,第二个分配给他,第三个,第四个,第五个,第六个,第七个,那么再来过呢,又像这样再再进行这样循环的分配,是这样的一个逻程逻辑大家看清晰了啊好,这个问题我们也得到了一个解答,就现在呢,Boss group其实只有一个了,我们再来看是不是这样子的。我这儿设置了一个一。也就是说我在这边设置了一个一,你们可以看到boss group里面的子线程,其实它只有一个了,这边还是有八个,我们再来第bug一下。
11:02
跑起来走debug下。看看这个一到底管不管用哈。我要走。走两步。好,再来走一步,那现在看boss group boss group打开过后呢,大家可以看到这里面只有一个了,看到没有。是不是一个event loop呀。诶,就是它下面只有一个I event loop这样的一个事件循环,那这个呢,还是有八个,因为你默认情况下看。现在就是一对八了。没问题吧,同学们。现在我们再来。解答第三一个问题就是关于。Channel和PI那的关系,还有就是我们这个ctx,就是上下文这个东西到底包含什么。这点也是非常重要的,而且我们我们在多说一句,大家看到是不是我们在这解析的时候,我们说过n IO event loop呢,还有自己的,还有自己的一个select,还有一个task。
12:09
Q,就是我们的任务队列,我们看这个还有没有啊,现在刚好刚好我们借这个机会再来跑一下。好,现在好像还没有,还没有,还没有退出,还在这个debug状态,看一下是不是这样子的,打开它。大家看我们每一个child里面有就是每一个event。L的路包含什么东西?是不是有个sector?是不是有,是不是每个select就有对应的select case,而且这边有可能有多个。那这是一个sector,还有什么呢?还有什么东西,大家看是不是有task。这个Q啊,他是个Q。是不是?那么下面还有exor,这个也很重要,后面还会说这是一个执行器,这个执行器呢,它是用一个外的factory给你生成的。对吧,那还有什么东西呢。
13:01
A。还有像他是不是only read only差的。还有其他信息哈,还有其他信息这边都可以找到,我们再来看worker group下面它不是有八个这样的n IO event吗?看看是不是每一个n IO event都有自己的独立的sector,你看这有个S。这个select这个实际类型啊,我们以前讲过际类型是select selected selection case select set select。对不对,然后它是1129,看到没有,这是1129,我们再看下面这一个。他是不是也有一个select,这个它是1144。是不是也就是说的的确确是证明了这样一个观点,就是每一个呢,I event lo有自己的sector。也就是他自己,相当于说你可以理解成我们每一个子线程也在这里不停的循环,怎么循环呢?就像刚才老师说的这个图。
14:04
哦,他也是在这里不停的循环,等待你相应的这个读写的事件,如果你这个读写的事件一旦来了过后呢,它就会驱动,驱动什么呢?驱动跟我们这一个event,呃,就是IO event loop关联的什么呀,Handler进行相应的处理。对second handler进行相应的处理。他会就就会他会去触发这个事情,调用我们的handlera,而这个handle呢,其实已经在这个paperonline里面了。OK,好,这个我相信同学们应该有点印象的,现在我们再来,呃,就是再来通过这个代码呢,我们再来看channel和pipeline,还有ctx关系,好,同学们我们再来进行一个第八个,这次呢,我们要要把这个断点下在哪里呢?我把这个断点下在这里,我重我重点是看ctx,同时呢,我再把他这几个信息打打出来。
15:00
我把什么打出来呢?把把它的这一个channel和它的管道拿出来,我们看看它的关系是什么。看看山了。China和PayPal。Pit。的关系。好吧,那现在,呃,同学们,同学们看到这里面呢。我们先来得一个吧,Ctx,从这个上下文我们是可以拿到这个channel channel的,我们搜搜一下。我就用。一个变量来收。点CR。好,大家看到知道为什么这什么意思吗?他说你这个地方其实这也执行了,他说要不要把这边这个值拿到过后,然后替换ctx这个东西,它是这个替换这一个。就替换这一个好,所以说我这就没有替换,如果我刚才选的这一个呢,他就会把下面这一个也给替换了,大家再看一下VR。
16:02
你看我点这个这个点的过,你是发现有没有这帮他也给你替换完了试一试吧,好就这就这意思,好这个channel我们也可以这样子去玩,待会我们看这个channel到底里面含什么信息,我们再把它的通道也拿到。通道怎么拿呢?通道怎么拿呢?拍on。因为这两者很容易让人产生一个误会,产生一个误会,拍拍也拿到了。好,还有这个CDX,待会儿我要我要好好看一下,其实这个拍on呢,你看它底层,其实它的本质啊,本质是一个什么呢?是一个双向链表。啊,这就涉及到一个,呃,数据底层一个数据结构的问题,双向链表。啊有什么呢,它涉及到一个出站入站的问题。初战。入账问题。好,同学们,我把断点先下到这里,好吧,待会我们就看三个,一个是ctx,一个是channel,一个是pipeline。那现在呢,我们来开始进行一个第八个。
17:04
先把。这些关闭一下。这些我先关闭了啊,我先关闭了。呃,整体这样子close一下就行了,Close。好,同学们,我们现在进行一个debug。进行第八个。认真听一下这块啊,这块只要这块突破了就好办了,好的。服务器is OK,现在呢我运行。我运行C。好的。运营起来,运营起来过后,断点已经下到这里了,我们先走两步。好,这边我们都走走完了,走完过后我们来看看这边的东西是什么啊,同学们看,首先看这里。CDX,我们看这里面包含什么东什么东西啊,看这里。首先我们看。关于China handler context呢?其实它真实的类型是devo China handler context里面包含的内容非常多,你看它有handler。
18:05
也就这个上下文包含了很多信息,甚至包含了你的。Ninety,这是,这是不是我们自己的呀?是不是我们自己,就是我们自己把一个自定义的ninety server handle加到那个pan,加到了那个管道里面去,结果呢,通过这个上下文我们也可以拿到。诶,大家看这个next很有意思,你看这个上下文,它还有next和这个pre,说明它其实是呃倍加,它其实是在这个双向链表,双向链表也能体现出它的特点,你看现下是inbound的,说明他目前是属于一个入站的状态。它是属于一个inbound,不是一个outbound,哎,你看这里面还有PE。是不是他还可以拿到这个PI呀,就是CX里面包含了PI,而且大家看这个PI有有点意思啊,Piper none PI none呢,它其实是debt China pipe烂,然后呢,你看它有害的。
19:04
它有头,它还有尾,说明太烂,本质其实是一个什么呀,双向链表。啊,它本质是个双向链表,而且大家有没有发现通过pipeline呢,我可以拿到channel,当然这个pipepeline和channel呢,它应该是一个对应的关系,啊,Pipeline和这个channel。看没有?你看这是1359,这是1373。好下面呢,关于这个,那么关于这诶这别别走了啊,我这跑跑跑跑完在在往下还还在这来看。好。好,接着看,还是找到拍。那你看这个拍呢,还可以找到与它对应的channel,这个channel里面有的有关于这个通道,这个管通道的信息也很多,你看包括我们刚才拿到的这个remote address local不是都有啊。你看是不是都有信息微商的权,所以说我们可以看到这个ctx,其实这是一个重量级的对象,它的信息量非常的大,诶你看他甚至还还能够反向拿到它是属于哪一个线程的,你看没有even the loop。
20:12
是不是他是,也就是说他现在是属于哪一个event loop。呃,这个东西。好,呃,下面呢,当然还有其他信息,我就不一个不一个个看到,不一个看到现在我们再来看我们这个channel,呃,Channel说完了,我们再看pipeline pipeline呢很也很有意思,你看这个pipeline呢,也又可以反向的得到这个channel,所以说我们说。我们说拍那和China,其实你我们可以认为是一个相互包含的关系,就是我中有你,你中有我,而且你看这个,这是1359,这边是1373,是不是跟刚才那看是一样的,那你是1359是1373,我们再看这边。China,你看China这边是1373。这是1373这边拍是1359是不是是同一个,他们是对应的吧,不会说,诶你在这个地方China里面取出的拍烂和和这个这边的pipeline不是一个,它是对应的关系,它是对应的关系。
21:15
好,那同学们,关于就是通过这个,通过这个分析呢,大家可以看到,其实整个这个关系大家也就看出来了,就说。China和pipe是相互包含,我可以有你,你可以有我,对吧,然后CX呢,这个ctx呢,它就更加的强大,它把这两个哎都给包含进去。都给包含进去,甚至包含了其他更多的信息。包含了更多的信息都在,也就是说通过这个ctx我们可以拿到拿到更多的信息。拿到更多信息。好同学们,那关于呃,关于这一个关于这块的分析呢,我们先到这里,大家看能否理解。
22:02
通过这个分析,我相信同学们对net模型应该有一个。呃,相对更加。呃,更加清晰的一个认识,好吧。好,关于代码的分析,我们就到这里。
我来说两句