00:00
那么前边呢,我们讲了一个actor自我通讯的这么一个题,那么把这个题呢,再做一个小结哈。当程序执行这么一句话的时候,这句话是关键,就是actor factory act of,他会完成如下任务,就这一句话就做了很多事,什么事呢?第一个act factory是我们这个actor system创建的第二个pro。里面写这个act呢,会使用反射机制创建一个actor的对象,比如说你这写的是AAA actor,那么创建的就是AA actor对象,如果将来你用的是这种形式,比如说后边我们会马上用到一种新的形式,什么呢?就是我们再去创建一个呃,Icon的时候呢,需要带入什么呀?参数,那么我们就用六的方式来创建它的实例,而且呢,中括号变成了小括号。
01:02
后面呢,写上我们的这个名称啊,这个act名称,呃,第三个。它会返回一个。Actor对象的代理,就是大家看到的actor。这个呢,是用来发送消息的。会在底层这个咱们看不到的,隐藏起来的,会创建一个PA message是一个线程词,用于分发消息。那么消息是发送到对应的那个ICU的mailbox啊,刚才那个图应该更加形象的说明这个问题了。然后呢,我们第五点会在底层创建对应的mabox,该对象是一个队列,可以接收dispat发送的消息,也就是说将来消息多了。比如说有很多别的actor,他自己的actor发过来,如果我们这消息多了,会会干什么呢?会在这个地方形成一个队列。
02:04
啊,也就是说将来呢,如果我们消息多了以后呢,它会在这地方形成一个队列。哦,就是比如说一个消息。啊,两个消息,那他消息队列一旦形成,他在推送消息给这个receive方法的时候,它是一个一个的往这边推的啊。这边谁收了他是一个,比如说这是第一个消息。这个是第二个消息,那么他就会按照一个队列形式把它把这个飘过来给他啊,然后再把第二个给他,以此类推啊,这样它会有一个这个队列的应用在这个位置。那么紧接着我们来看第六一个mailbox实现的是run label是一个线程,因此它一直运行并调用act的receive方法。因此当patch发送消息到mailbox时,Act receive方法就会得到消息。好,那么大家看到这种方式表示的就是,呃,把这个消息发送到这个refer对应的act的mailbox,好,这样呢,我们就把它做一个小结就说完了啊说完了好,我把这个呢小结也给大家整到这里啊,上题啊,代码。
03:17
代码的小结和示意图。好,这个呢,我们就说到这里来一个标题三,下面我们接着讲新的案例。好,刚才这小节呢,我总结了一下。诶,总结了一下,好给大家放到这儿啊,放这儿这是刚才的总结的一个套路。好给它来一个这个符号吧,然后呢,下边还有对吧,下边还有这么几点。啊,这么几点也把它拉过来。好的,那关于这个整整理到这,然后还有示意图,我画了一个啊,一个示意图的说明。这个示意图呢,我在这儿现场画了一个。
04:03
啊,就是这个图。啊,就这个图。好,给大家放到这里来。那下面呢,我们来看一个新的知识点,就是什么呢?I之间的通讯。那什么意思呢?现在呢,我们有这么一个需求,就是编写两个actor。分别是a actor和b actor,那么a actor和b actor之间呢,可以相互发送消息,就是你给我发一个消息,我给你回送一个消息。对,那比如说你看我这有一个示意图,比如说a actor先出招。A先出一招,他输出适当,OK,那么这边说我打。然后B假设模拟是乔峰,然后他说提莫看我降龙十八掌对吧,然后这边。他打过去过后呢,这个A呢,我们模拟是一个黄飞鸿对吧,他说诶厉害,我来一个佛山模拟脚,这样打来打去的啊,打来打去就这样子,就你给我发一个消息,我给你回个消息,你给我发一个消息,我给你回个消息,让他们之间相互通讯,那么这样呢,我们可以加强对艾克传递机制的一个理解,这就是我们的一个需求。
05:15
那有了需求过后呢,我们还是对照这个画一个示意图,帮助大家理解。好,待会儿我们要做的是两个actor,也就是说待会儿要做的是a actor,发一个消息到b actor,那么它是怎么发的呢?首先。A actor。他要给自己发,那很简单,因为他有自己的持有,那么a actor作为一个主动者,主动发起者。他必须先要持有B的这个。Refer,所以说有一个前提,什么前提呢?就是说我们在创建a actor的时候,我们首先要拿到a actor引用,因为你A开actor发消息的时候,肯定是在receive。里面发,也为他的消息是从这发出去的,好到时间我们会这样子,在a act里面要持有它,有自己的同时还要持有B,那么发消息仍然发给dispa dispa message呢,会把这个消息发送到B。
06:22
Actor的mailbox,那么b actbox呢?拿到的消息过后推送给b actor的receive方法。那么对于CF方法,他拿动过,怎么把这个消息你打我一下,那么B是乔峰,那乔峰怎么把这个消息又回送给这个A呢?他这里通过cer。可以拿到。发送给我的那个I的引用,就是说它会自动的通过这个center方法拿到引用,也就说这个持有消持有这个其实消息里面带的用只是用send提取出来了,然后用send再一发,他又怎么发的呢?他又把这一条消息回送给我们的这个。
07:04
地方。啊,当然也是经过这个dispat了,也是经过dispat,我就没有这么话了,那么他拿到以后呢,这个a act ma box一直运行,他又把这个消息推送给。他了,他拿到过程,他又给他回一个消息,意思就这样不停的这个打来打去,但打的时候都是这样子过来过去的啊好,现在呢,这个示意图有了,我们就可以来写一下这个代码啊,写下这个代码,大体这个代码呢,分成三大块,一大块呢是我们的a actor。一大块,哎,这个是b actor,这是我们的a actor,然后这边呢,是我们的一个actor games,让他来完成一个调用的实现。调用的实现好,现在呢,我们开始来写这个代码。我们来一起完成啊,各位同学。那我还是在这里建一个包。
08:00
那这个包呢,我们叫com点。come.at硅谷点阿卡。第二是两个actor,所以说我叫ACTOR4啊,ACTOR4。OK。好,那现在呢,我们新建三个文件,第一个文件我们专写a actor。没问题。好,紧接着我们再来建一个b actor。这个b actor,我们也把它建起来。我们再建一个,呃,调用这两者的这么一个APP,好,我们叫做叫做actor games。Game JA,好,这个呢也很简单,就写到这肯定是个object,它来调用好,我们应该先写哪一个呢?啊这样子,因为我说了我们这个艾主要是取决于谁先主动发起这个行为。主动发起的,他一定要持有对方的这个引用才能发起,否则这个肯定是白搭。
09:04
因此呢,我我们刚才说的A先做这个事情,所以说我们这个地方呢,这样去构建开写了啊,首先我们。给他来一个继承,继承a actor,好,这个就完事,然后呢,我引入包。同时我实现刚才我们所说的这个方法。好。写上去就可以了,那一般呢,我会把它返回这个receive写上,不写上应该也可以啊,也可以好,现在呢,我们。来做一个动作啊,来做一个动作,首先。我们要触发这个行为,这边有个问题。就是。你这个艾克要触发起来,让它动起来呢,我们首先来一个这样的行为,就是你先给我发一个四大,我再开始打,所以我先接受一个四大,这个可能可能主要这个地方主要的目的就是让我们这个AI能够运行起来。
10:03
啊,当然这个名字不一定叫十大教,别的也可以,那我干什么呢?我就写出一句话就说啊,就说根据我这个示意图啊,刚示意图我是这么说的。叫做AA actor出招了,十大OK。好,我写一个东西。A actor就是A。Actor出装。出招了。哦,十大。开始了。啊,是的。OK好,呃,那么这个时候,呃,这个时候他发出这个行为以后呢。他要干什么事情呢?好,他要去触发一个出招的行为。所以说这个地方我们要去想一想,他怎么出招呢?好,他就给自己发了一个消息。比我这样设计的啊,你不然的话,待会你发过去,别人要给你回个消息,人家肯定不会,不会回一个star。
11:05
肯定别人说啊,我打对吧,比如说我这写了一个消息,给自己发一个什么消息呢,我打。啊,我打。那么这个我打是发给谁了呢?发给我自己了,是这个样子的吧,这个是发给我自己,给自己发是可以的。发给自己了。发给自己,呃,那你发给自己的话,我肯定是能够收到这个消息的,所以说我说发现如果有人有人给我发一个,我打。好,那下面呢,我就好办了,如果我发现有人给我发了一个,我打就相当于说开始攻击了。那一旦开始攻击呢,我现在就可以干什么呢,我现在就给。给谁呢?给这个b actor。B这个邮箱。给b actor发出一个消息。发出消息。那么你要给别人发消息有一个前提,就是你必须要持有B的引用。
12:05
好,这个问题呢,就要我们来解决啊,这里需要持有。词有什么呢?B的引用,哪个引这个引用。I引用G什么呢?BB的这个refer好,这个b refer别人是不会给你的,你只能是在构建这个I的时候传进来。因此呢,我的思路就简单,我是这样做的啊,那你呢,在构建的时候,我来拿到这个东西,那就是这样写叫B。Actor。引用。轴类型是actor。RA。F。没问题,那么你给我以后,我在这个地方呢,就拿一个这样的引用,你给我吗?我当然在构建时就可以拿到了,那我怎么拿到呢?非常的简单,我这直接写叫做B啊,这样写啊就叫B。
13:12
Actor。啊,这样传过来的话。啊,比如说我们就叫actor引用,这样这样我更清晰一点啊,叫actor的一个引用,我这样写b actor。啊,等于等于什么呢?你传进来的这个东西。那我就拿到了啊,当然你要写个类型,也可以说老师我把这个类型写上,那更明确啊,我们第一次呢,把这个类型写上也很明确,好,我在这地方构建的时候就已经有了,那简单的很,我就干什么呢,我就用这个B。发出一个消息,说什么呢?就是按我这个流程开始打了,老干什么都说,呃,比如说我说。我就先发一个这样式啊,就是。这个是这个是,呃,我是黄飞鸿是吧,黄飞鸿的话呢,就说直接发一个我打是吧,我打。
14:09
这地方我应该怎么给他发一个消息呢?啊,我应该发一个这样的消息,就是呃,就是我直接说这个,我说我是谁啊,这样子大家看着行,A actor,我就按这个写就行了。按照写就是,呃,A actor是黄,黄飞鸿啊,A actor谁呢黄飞鸿。黄飞。啊,黄飞鸿对吧,然后呢,我说啊,我说这个厉害厉害,然后呢,看我佛山五角啊看。好看我佛佛山无影脚,当然这个消息呢,理论上说应该是没有必要这样子,这样就是别人拿到的消息没办法处理,所以说你还变化,因此呢,我们可以把这个信息这样写,改写一下这样写。
15:02
招这样写,我们先在这输出这句话,就是我要,我要出的是什么招,我先说一下。对吧,我说我出的是这招。然后呢,再给对方发一个我打,让他知道我出招了。诶,这样子他就可以动起来吗?啊,就是我打这个时候,这个消息就发给谁了呢,发给了。发给了B,就是这个,就是发给了B的那个邮箱。好好,那么B邮箱拿到这个东西过后呢,他肯定也要去处理,现在这样子啊,我待会。B作为,A作为一个起始,所以我先调一个star,让他跑起自己来,然后他发现有个我打就直接。说出一句话,然后呢,给B发出一个我打,那么。B actor呢,肯定就能接收到这个消息,所以说我也让他继承一个actor。
16:00
没有问题,那既然actor呢,我来引入,再把这个B里面的方法写一遍。好,这个时候我们怎么写呢?好老规矩,我还是喜欢,就是写上这个refer啊receive,那这边我们就直接kiss嘛。这个他这个B作为一个被动者还是比较容易的,他就说如果我接受有人说我打,那我就知道有人给我出招了,然后呢,我就干什么呢,我就说一句话什么呢啊,我是be actor。Be actor是谁呢?是乔峰啊,我是乔峰,然后呢,我说提猛啊提猛。提猛,然后呢,看我看我这个降龙十八掌,降龙十八掌。二降降龙十八掌。好,给他一张,打完了过后呢,我们也要给他杀发个消息,问题来了,现在b act要给A发一个回声的消息呢,我们没有这个AX应用,但是我们可以用,通过这个三。
17:07
这个升方法呢,是从这个X这边。继承下来的这个send呢,可以获取到谁给我发送的这个消息的那个对应的I的引用,诶可以获取到。发送消息。的A的。应用。啊,那这就简单了,就深。也给他来一个消息,注意啊,这个地方。这个符号一看就应该是操作符的一个重载啊,待会呢,我们可以lawyer,他也说我打。啊,我打,那么我们来看一下这个是不是一个方法。好,同学们看到它其实就是一个方法,发送一个message,类型any。啊any,然后呢,这边还有一个值对吧,就叫隐式参数值。
18:01
那这个地方他他一打了就发过去,这边一一发出我打这边呢,他又接收到我打,哎,他说我打,然后说我又给你说看我分我也打你,然后这边说到我打,然后我也打你,哎这样就打起来了。啊,就无穷无尽的打起来,那你可以设计一个,比如说我们在100招之内啊,不分胜负我们就结束了,对吧,你可以做一个计数器,如果提到100兆了,不分胜负了,我们就退出。啊,这个呢,大家想怎么去设计好,写完了以后呢,我们来看怎么调用是一个关键啊,我们来看看怎么调用是个关键,那我这写个主函数啊,当然你要不写主函数,你也可以这样玩。说我直接写个APP。对吧,那这里面呢,我们还是老规矩,首先呢,要创建这个IC4特。对吧,那么actor system呢,也很简单,Act system system a actor system,呃,那么我在里面起个名字,比如说这个叫工厂吧,Aor。
19:07
Actor的一个工厂factory。好,我们给它一个变量。啊,给他一个变量,然后呢,这边我们先创建谁呢?显然我们要先创建B,为什么呢?因为A它是需要你创景啊,A是需要你传入一个B的一个引用的,因此呢,你肯定要先创建B。才能给A传进来,因此呢,我们第一步先要创建,对先创建。创啊创建B这个act的。诶,这个IO的一个这个这个引用。啊,或者叫代理,有些喜欢,有些人喜欢把他叫代理也可以。那怎么创建呢?非常简单点对吧,我们的,但这个时候注意有一点注意事项了啊purpose。
20:03
这个地方呢,我们不能够,我们不能够这样创建了。啊,这个呃,对B还是可以的,B呢,我们直接把这个类名字拿过来,让他用反射机制来创建,我说取个名字叫做B。Actor。好,然后呢,点VR。好,我们得到一个B啊,这个私有呢,你呃,要不就先去掉吧,咱们先不要做私有的。好,就把它做成一个这样类型的。好,然后这边拿到,拿到过后呢,我们下一步就来创建什么呢,创建这个A。Actor的一个引用,那这个就简单了,怎么简单act.act of,我们写上purpose,好,此时此刻同学们注意啊,我们这个时候创建呢,就要根据它这个构造器来创建了,那肯定不能简单写个类名了,因为人家有。
21:02
参数。对吧,那有既然有参数呢,那我显然就应该用六,六的话,这边写小括号用六一个什么出来呢。六一个我们的a act传输参数,这个参数就是刚才你的这个B引用,因为这样就达到了,我来用它。哎,我们用它,然后呢,同学们后边呢,给它取个名字,比如叫做AI写完了。好写完了,那写完以后呢,我们现在呢,给它分配一个变量点VR。好,给它分割a actor的引用,现在呢,我们要开始启用了啊,谁先动手呢?好,显然我们说了黄飞鸿先动手,他要动手,他就要触发这个行为,他先干什么呢?大家看我刚才已经写完了,我先让他发出一个十大。发出一个是,当然你要说我直接发我打也行,对吧,说我直接说我打,那么这边他就触发了这个黄飞鸿啊,他说厉害,看我佛山五角,那么这边发这个也可以,但是呢,我这做了一个适当的一个处理,对吧,实际上你直接发我打也是可以的,也是我可以的,那么我们来玩一把,现在呢,我们让这个黄A艾克先出招。
22:23
A。Actor。A actor出装。那出招也很简单,就a refer。看好,让他直接说一个star。好,现在呢,这个一出发,我们看两者是不是就动态的跑起来了啊,来运行一下看看有没有问题。好,我们运营起来过后呢,我们看到这两者,诶你看这个太恐怖了,打的太快了啊,打的太快了,这这个不行,这个不行啊,就看不到这个效果,怎么办呢?我们休眠一下,让他们啊别出到太猛了,就真的是成了佛山无影脚了,那也不行,那这样怎么办呢?诶我们让他休息一下。
23:05
thread.sleep对吧?呃,我们每隔一一秒钟出一下招,那就休眠一下,诶休眠一下,同样让这个,呃,乔峰呢,也休眠一下。就出招的时候至少要有一秒的反应时间,再来让一下。好,现在呢,我们看到这个效果就已经出来了,你看对吧。黄飞鸿先出招了,诶,乔峰说,诶,这个就打起来了。那打的打不行的,反正就是永远无穷无尽,无穷无穷无尽对吧,直到他们累死也打不完,那同学们想一想,如果我们将来想加一个退出功能,比如说如果我要求大家完成这样一个功能,你们看看能不能做完,怎么做完呢?就是说出招100招之后。大家就。退出了就不要再打了啊,你们想想这个能不能实现对吧,就说我提一个要求,就是100兆过后呢,咱们就不玩了,就这100兆后。
24:04
100招。100周后就干什么呢?就退出了。啊,这个东西其实挺简单的,你只需要在一个action里面加一个参数,它不停的累积嘛,啊到了100的时候,我干脆发现100我就直接。用我的那个停止我自己,你那边到了100呢,也停止我自己啊,停止完了过后两个就停了,停完了过后,那么有一个呢,就退出终止这个actor,大家可以尝试着去写一写,好代码也很简单,好经过这个案例呢,我相信同学们对我们这一个act的一个通讯就更加理解了,对吧,相对来说比刚才呢要进一步了,好我把这个笔记给同学们整理一下。那刚才我们讲了一个什么呢?诶,我们讲了一个actor模型的2ACTOR之间的一个通讯机制,来快速的整理一下标签。
25:00
走一个,那首先呢,我把这个应用需求给大家写出来了。这是我们的应用实例三,一共呢,有这么三个要求。好第一个对吧,第二个。对,那么第三一个呢,就是。呃,就就这两个需求啊,这还有一个第三一个。好,相互发送消息呢,这有一个图也给大家拿过来,我们直待会呢把代码发过来就可以了。好,这是它的一个对应图,那么在讲讲写这个代码之前呢,我做了一点这个什么呀,做了一点这个它的两个艾通讯机制的一个图解。一给大家拉过来,哎,就是刚才讲的这个图解啊,两个图图解,那图解呢。啊,这个是图解,图解的话呢,直接把这个拉过来看一下就可以了。
26:01
好。大家一看就清晰了。那么我们对应的代码呢,我这也写完了,代码一共有三个对吧,我们对应的代码看一下,诶对应的代码也很简单,对应代码呢就是代码,代码如下。诶,把这个题整理一下。标题三代码我们一共写了三个文件对吧?一个是actor。这是主动者。他主动发起了这个攻击,那么他是主动者。这地方我写个名称叫a actor。好,就是AI scanner。紧接着呢,我们又写了一个b actor。对,这是我们的b.scan。那B我们写什么东西了呢?各位同学,B呢,就是刚才老师写的这一段代码,更简更简单。啊b actor是这段代码,还有一段呢,就是调用或者是协调,这两者之间的一个叫什么呢?叫actor game。
27:08
Or actor game?点scanner,这段代码呢,是完成了一个调用的任务,这是刚才写的这段代码。好,同学们,关于这个什么呢?就是他们两者之间的案例,说完了我们看这有没有总结,再来简单的总结一下啊,总结一下两个act的通讯机制原理小结,两个act通讯和自身发消息基本一样,只是需要注意的是,如果a actor在需要给b actor发消息时,则持有b actor的引用或者叫代理。那么可以通过创建时传入b actor代理对象。搞定,那么当b actor接收到在save方法里面接收到消息后需要回复时,通过三这个方法就可以。
28:05
二就可以获取到发送act的代理对象啊,就是通过send就可以获取到act的代对象,那么你给我发的,我就给你回送给你。那么这里呢,我留了一个题,就是如何理解A的receive被方法调用,就是a receive方法被调用。我刚才讲了,其实回答很简单。刚才呢,我们已经说过这个事情了啊,怎么理解呢,第一点。第一点啊,就是actor actor都对应每一个actor。哎,每个每个。每个对应一个邮箱,对应一个mailbox。这是第一句话,那么mailbox干什么呢?它又实现了mabox,实现了这个runable的接口。也就是他一直处于运行的状态,它是处于处于一个运行的状态,这第二句话,第三句话,当当有消息到达,到达这个邮箱时,邮箱时。
29:15
该邮箱就会干什么呢,就会去调用这个I的receive方法。Receive I VR方法相当于干什么呢?相当于把消息推送过去了。方法将消息,将消息推送啊,推送给这个这个receive方法。所以说大体就是这样去理解就可以了啊,没有任何问题,那么这样至少能够解决一个大家感觉很奇怪的问题,什么问题呢?就是你在整个过程中,你发现我们没有显示的调用,没有显示的调用这个receive方法,它凭什么?就用起来呢,因为底层有个mailbox在帮我们不停的做这个工作啊,他在消息到他就推给你,一消消息到就推送给你。
30:05
啊,所以说这个呢,机制它就解决了我们一个同步的问题,我不会一直同步,对吧,你给我我就处理,你不给我,反正我就写到这儿,你来了消息我就处理,你不来消息我我也不用等。我不至于你这个消息怎么到达,我不关心,比如说刚才我们这个消息从这从你这个A发给B,可能经过了很多很很久很久。我不需要关心,而且我发个消息,发完过后,你什么时候回应,我也不关心,你是一分钟以后回应,还是一个小时以后回应,我都无所谓,因为你只要给了我,我总会得到,我在处,你什么时候给我,我怎么时处理,哎,这个其实特别像阿贾克斯的那个回调。啊,因为整个调用的机制全部交给了我们的这个模型。好,这就是他的这么一个讲解,截取一段视频。
我来说两句