zoukankan      html  css  js  c++  java
  • 关于并发模型 Actor 和 CSP

     

    最近在看《七天七并发模型》这本书,在书上介绍了 Actor 和 CSP 这两种并发模型。这两种模型很像,但还是有一些不同的地方。看完之后,比较困扰的是:

    在什么场合使用哪种模型比较好呢?

    在网上查了一些资料,在没有实现使用这两种模型进行编程的情况下,结合网上的资料,把自己的思考记录一下。下面先说说两种模型的不同点吧。

    一,主要的不同点

    1,关于消息发送方和接收方。

    • Actor:注重的处理单元,也就是Actor,而不是消息传送方式。发送消息时,都需要知道对方是谁。

      这里的“都需要知道对方是谁”的意思,当ActorX要给ActorY发消息时,必须明确知道ActorY的地址。ActorY接收到消息时,就能够知道消息发送者(ActorX)的地址。返回消息给发送者时,只需要按发送者的地址往回传消息就行。

    • CSP:注重的是消息传送方式(channel),不关心发送的人和接收的人是谁。

      向channel写消息的人,不知道消息的接收者是谁;读消息的人,也不知道消息的写入者是谁。

    两者比较看来,CSP把发送方和接收方给解耦了,但这种解耦带的好处是什么呢?

    2,消息传输方式

    • Actor:每一对Actor之间,都有一个“MailBox”来进行收发消息。消息的收发是异步的。
    • CSP:使用定义的 channel 进行收发消息。消息的收发是同步的(也可以做成异步的,但是一个有限异步)

    看了《并发之痛 Thread,Goroutine,Actor》这篇文章的中,关于 Actor 和 CSP 不同点的说明,感觉有一点可能留意:

    Actor 模式消息传输,只有一个通道(MailBox),所以无论什么“类型”的消息都可能发过来,所以要做好模式配置。而 CSP 中的通道(channel)类型是定好的,而且两个对象可以可以使用多个通道传输消息。(CSP 把通信给细化了,让你在通信时有多种选择,例如:用一个 channel 传一类数据,用另一个 channel 传另一类数据)

    这就和MQ的机制有点像了。在通过MQ传输消息时有两种选择:

    • 选择把这个消息发送到哪个 Exchange(类似 channel)里,对于不同的 Exchange 可以有不同的处理程序。
    • 还可以把数据发送到一个 Exchange 里,然后设置分发规则,选择不同的处理程序。

    (不知道这点对选择哪种哪种模型有没有什么帮助?)


    总结:没有看到两者不同点,给某一方带来什么特别明显的好处。

    二,从写程序的角度来看,有什么不同呢?

    1,假如,要做“关于取得RSS文章的单词数”这样的程序的话:

    CSP:

    • 步骤1:定义几个channel,保存不同处理的之间的数据: 
      1,新文章ch 
      2,文章内容ch 
      3,单词数ch

    • 步骤2:然后写相应的处理程序: 
      1,新文章URL处理(把得取的新文章的URL,写入“新文章ch”) 
      2,新文章内容处理(把新文章内容读取下来,写入“文章内容ch”) 
      3,单词数统计(对文章内容进行单词个数统计,写入“单词数ch”) 
      4,文章单词数累加(读取“单词数ch”,把各个文章单词数进行累加)

    • 步骤3:在主程序中,定义上面的几个channel,再调用几个处理程序,并把channel当成参数传给处理程序

    Actor:

    • 步骤1:定义控制Actor,控制程序流程,功能如下: 
      1,当收到指令是“新文章URL处理”的话,调用“新文章URL处理”Actor,并把处理结果返回给调用者。 
      2,当收到指令是“新文章内容处理”的话,调用“新文章内容处理”Actor,并把处理结果返回给调用者。 
      3,当收到指令是“单词数统计”的话,调用“单词数统计”Actor,并把处理结果返回给调用者。 
      4,当收到指令是“文章单词数累加”的话,调用“文章单词数累加”Actor,并把处理结果返回给调用者。 
      (以上的每一个指令的执行,都可以做成并行的)

    • 步骤2:定义指令相对应的处理程序。

    • 步骤3:主程序,向“控制Actor”发指令,并把每次指令的结果当成参数,传给下一次的指令调用。

    2,如果需求增加,在单词数统计时,去掉”of/to/and”这些单词的话,CSP和Actor要怎么做呢?

    CSP:

    • 主程序: 
      1,定义一个新的ch 
      2,并增加对内容过滤程序的调用。 
      3,传给“单词数统计”程序的ch,要修改成新定义的ch

    • 子程序: 
      1,新加一个处理程序。

    Actor:

    • 主程序: 
      1,增加对内容过滤Actor的调用
    • 控制Actor: 
      1,增加一个新的内容过滤指令
    • 子程序: 
      1,定义一个新的内容过滤Actor


    总结:从最初的需求做成,到根据新需求修改上,感觉不两者差别并不大。 
    (可能因为没有实际编码过,在做一个需求或是一个大一点项目时,会感觉到不同吧。)

    其它参考

    1,《并发之痛 Thread,Goroutine,Actor》文章的最后一部分:

    CSP的模式比较适合Boss-Worker模式的任务分发机制,它的侵入性没那么强,可以在现有的系统中通过CSP解决某个具体的问题。它并不试图解决通信的超时容错问题,这个还是需要发起方进行处理。同时由于Channel是显式的,虽然可以通过netchan(原来Go提供的netchan机制由于过于复杂,被废弃,在讨论新的netchan)实现远程Channel,但很难做到对使用方透明。 
    而Actor则是一种全新的抽象,使用Actor要面临整个应用架构机制和思维方式的变更。它试图要解决的问题要更广一些,比如容错,比如分布式。但Actor的问题在于以当前的调度效率,哪怕是用Goroutine这样的机制,也很难达到直接方法调用的效率。当前要像OO的『一切皆对象』一样实现一个『一切皆Actor』的语言,效率上肯定有问题。所以折中的方式是在OO的基础上,将系统的某个层面的组件抽象为Actor。

    这段话中,有一点可能要注意

    而Actor则是一种全新的抽象,使用Actor要面临整个应用架构机制和思维方式的变更。

    2,《Scala与Golang的并发实现对比》:关于 Actor 和 CSP 的一般实现方式,不了解实现的可以看一下。 
    看了一些例子,感觉

    参考文章:

  • 相关阅读:
    668. Kth Smallest Number in Multiplication Table
    658. Find K Closest Elements
    483. Smallest Good Base
    475. Heaters
    454. 4Sum II
    441. Arranging Coins
    436. Find Right Interval
    410. Split Array Largest Sum
    392. Is Subsequence
    378. Kth Smallest Element in a Sorted Matrix
  • 原文地址:https://www.cnblogs.com/williamjie/p/9466234.html
Copyright © 2011-2022 走看看