Actor 模型 / CSP模型 / 共享内存模型

 

CSP模型 通讯顺序进程,其实就是基于channel的消息通讯,在ROS中,这种channel称做主题topichtml

erlangactor的表明性语言,goCSP的表明性语言python

 

还有几个没怎么看的答案,不过都差很少了,这个讲历史比较多,也比较透彻,颇有用,须要再仔细看!git

https://stackoverflow.com/questions/22621514/is-scalas-actors-similar-to-gos-coroutines/22622880?r=SearchResults#22622880程序员

https://stackoverflow.com/questions/20171442/is-communicating-sequential-processes-csp-an-alternative-to-the-actor-model-in?r=SearchResultsgithub

http://en.wikipedia.org/wiki/Communicating_sequential_processes#Comparison_with_the_Actor_Model编程

理解ACTOR和CSP模型,有python源码。多线程

https://www.codercto.com/a/9890.html并发

 

Actor 模型与Object模型框架

Theron框架是一个基于Actor模型的并发编程的C++库。而Actor模型使得Theron框架能够直接有效的建立并行分布式的应用。Theron框架提供了不少轻量便携的函数接口API,可使用在LinuxWindowsMacARMMatlab环境。 异步

咱们知道面向对象编程中使用的是Object模型,宣扬一切皆是对象,数据+行为=对象。而Actor模型则认为一切皆是Actor,Actor模型内部的状态由本身的行为维护,外部线程不能直接调用对象的行为,必须经过消息才能激发行为,也就是使用消息传递机制来代替Object模型的成员方法的调用,这样就保证Actor内部数据只能被本身修改。Actor模型=数据+行为+消息。 

可是C++是一种面向对象的语言,因此最终仍是经过类来封装这种actor的机制,多线程的实现也是依靠内存共享的多线程机制设计的,只不过这些事情Theron源码已经帮咱们完成了,咱们直接使用它给出的类接口便可。Theron框架的多线程基础支持pthreads,Windows threads,boost::thread和C++11 threads四种传统类型来构建。多说一嘴,由于Theron框架在C++中说到底仍是经过类封装实现Actor模型的,天然咱们直接经过类对象调用类中方法数据。可是为了保证Theron框架生态的完整性,而且真正体现actor模型的优越性,咱们仍是不要如此为好。 

基于Object模型与Actor模型区别如图3所示。

 

 

这里写图片描述

(a) 

 

这里写图片描述

(b) 

图3 基于Object机制与基于Actor机制的比较 

从图中能够看到,类A的对象成员方法调用类B的对象成员方法须要通过A::call调用B::called方法,而后等待B::called方法执行完成而且返回响应,最后A::call继续上次调用的地方后面执行下去。而在Actor模型中,Actor A先发送消息给Actor B,而后即刻就返回继续执行下面的程序,而Actor B中收到消息被唤醒和Actor A并行执行下去。 

至此,Actor模型就能够看出这种消息机制的线程调用最大好处是非阻塞的,多个线程能够同时并发进行,无需等待被调用方法执行完成返回消息的响应。固然,看到此处你们或许跟我同样有一点困惑的地方,即万一咱们后面的程序须要当即使用它返回的响应消息怎么办呢?其实这也算Actor存在的一点不足之处,须要咱们在设计多线程前考虑你的程序到底适不适合这种机制,后面咱们会再详细描述。 

--------------------- 

做者:无鞋童鞋 

来源:CSDN 

原文:https://blog.csdn.net/FX677588/article/details/74359823 

版权声明:本文为博主原创文章,转载请附上博文连接!

 

3.2 Actor模型与共享内存模型不一样点 

Actor这种独立并发的模型,与另外一种共享内存模型彻底相反。Actor之间经过消息传递方式进行合做,相互线程独立。随着多核时代和分布式系统的到来,共享内存模型其实不适合开发的。咱们以酒店厨房作菜为例,如图4所示。

 

 

这里写图片描述

图4 Actor模型与共享内存模型的比喻图示

 

①、单线程编程,如图4(a)——犹如酒店只有一个厨师员工(一个线程),全部菜按点菜顺序与工序完成到底就行; 

②、共享内存的多线程编程,如图4(b)——犹如酒店厨房是由洗菜工,刀工,掌勺,服务员等(每一个人是一个线程),他们之间的确能经过合做能比一个厨师完成全部工序要快。咱们须要考虑的是菜至关因而他们共享的资源,每次只能一我的在对其作处理,虽然有多道菜品,可是总会在穿插间存在等待。 

③、Actor模型的多线程编程,如图4(c)——犹如酒店有多个厨师,分别是川菜师傅,鲁菜师傅,徽菜师傅等等,他们只要接到客人点菜的需求,整我的独自完成相对应菜系的工序,之间无论对方师傅要干吗,如此多线程工做就大大增长了效率,而且不存在互相等待资源的状况,作好了本身发消息给服务员端菜便可。 

这样咱们就能够看出Actor模型异步消息传递来触发程序并行执行,虽然不如直接调用来的直接而方便,可是它可让大量消息真正意义上同步执行。同时消息让Actor之间解耦,消息发出去以后执行成功与否,耗时多少等等只要没有消息传递回来,一切都不在与发送方有任何关联。这样也保证了,咱们不须要在共享环境中与同步锁,互斥体等经常使用基础多线程元素打交道。 

--------------------- 

做者:无鞋童鞋 

来源:CSDN 

原文:https://blog.csdn.net/FX677588/article/details/74359823 

版权声明:本文为博主原创文章,转载请附上博文连接!

 

 

这篇文章讲解了如何使用netmq来实现个简单的actor,同时也讲解了actor model的基本概念,与共享内存模型的区别

https://github.com/zeromq/netmq/blob/master/docs/actor.md

 

actor模型与CSP模型

https://www.jdon.com/concurrent/actor-csp.html

 

卧槽,ROS的主题就是CSP模型中的CHANNEL!!!

Actor模型和CSP模型的区别

Akka/Erlangactor模型与Go语言的协程Goroutine与通道Channel表明的CSP(Communicating Sequential Processes)模型有什么区别呢?

首先这二者都是并发模型的解决方案,咱们看看Actor和Channel这两个方案的不一样:

Actor模型

在Actor模型中,主角是Actor,相似一种worker,Actor彼此之间直接发送消息,不须要通过什么中介,消息是异步发送和处理的:

actor模型

Actor模型描述了一组为了不并发编程的常见问题的公理:

1.全部Actor状态是Actor本地的,外部没法访问。

2.Actor必须只有经过消息传递进行通讯。

3.一个Actor能够响应消息:推出新Actor,改变其内部状态,或将消息发送到一个或多个其余参与者。

4.Actor可能会堵塞本身,Actor不该该堵塞它运行的线程。

更多可见Actor模型专题

 

Channel模型

Channel模型中,worker之间不直接彼此联系,而是经过不一样channel进行消息发布和侦听。消息的发送者和接收者之间经过Channel松耦合,发送者不知道本身消息被哪一个接收者消费了,接收者也不知道是哪一个发送者发送的消息。

channel模型

Go语言的CSP模型是由协程Goroutine与通道Channel实现:

  • Go协程goroutine: 是一种轻量线程,它不是操做系统的线程,而是将一个操做系统线程分段使用,经过调度器实现协做式调度。是一种绿色线程,微线程,它与Coroutine协程也有区别,可以在发现堵塞后启动新的微线程。
  • 通道channel: 相似Unix的Pipe,用于协程之间通信和同步。协程之间虽然解耦,可是它们和Channel有着耦合。

 

Actor模型和CSP区别

Actor模型和CSP区别图以下:

ErIang  в

Actor之间直接通信,而CSP是经过Channel通信,在耦合度上二者是有区别的,后者更加松耦合。

同时,它们都是描述独立的流程经过消息传递进行通讯。主要的区别在于:在CSP消息交换是同步的(即两个流程的执行"接触点"的,在此他们交换消息),而Actor模型是彻底解耦的,能够在任意的时间将消息发送给任何未经证明的接受者。因为Actor享有更大的相互独立,由于他能够根据本身的状态选择处理哪一个传入消息。自主性更大些。

在Go语言中为了避免堵塞流程,程序员必须检查不一样的传入消息,以便预见确保正确的顺序。CSP好处是Channel不须要缓冲消息,而Actor理论上须要一个无限大小的邮箱做为消息缓冲。

http://www.javashuo.com/article/p-rpposmvt-hb.html

源于从Erlang到Go的一些思惟碰撞,就像当初从C++到Erlang同样,整理下来记于此。

Actor

Actor模型,又叫参与者模型,其”一切皆参与者(actor)”的理念与面向对象编程的“一切皆是对象”相似,可是面向对象编程中对象的交互一般是顺序执行的(占用的是调用方的时间片,是否并发由调用方决定),而Actor模型中actor的交互是并行执行的(不占用调用方的时间片,是否并发由本身决定)

在Actor模型中,actor执行体是第一类对象,每一个actor都有本身的ID(类比人的身份证),能够被传递。actor的交互经过发送消息来完成,每一个actor都有一个通讯信箱(mailbox,本质上是FIFO消息队列),用于保存已经收到但还没有被处理的消息。actorA要向actorB发消息,只需持有actorB ID,发送的消息将被当即Push到actorB的消息信箱尾部,而后返回。所以Actor的通讯原语是异步的。

从actor自身来讲,它的行为模式可简化为:

  • 发送消息给其它的actor
  • 接收并处理消息,更新本身的状态
  • 建立其它的actor

一个好的Actor模型实现的设计目标:

  • 调度器: 实现actor的公平调度
  • 容错性: 具有良好的容错性和完善错误处理机制
  • 扩展性: 屏蔽actor通讯细节,统一本地actor和远程actor的通讯方式,进而提供分布式支持
  • 热更新? (还没弄清楚热更新和Actor模型,函数式范式的关联性)

在Actor模型上,Erlang已经耕耘三十余载,以上提到的各个方面都有很是出色的表现,其OTP整合了在Actor模型上的最佳实践,是Actor模型的标杆。

CSP

顺序通讯进程(Communicating sequential processes,CSP)和Actor模型同样,都由独立的,并发的执行实体(process)构成,执行实体间经过消息进行通讯。但CSP模型并不关注实体自己,而关注发送消息使用的通道(channel),在CSP中,channel是第一类对象,process只管向channel写入或读取消息,并不知道也不关心channel的另外一端是谁在处理。channel和process是解耦的,能够单首创建和读写,一个process能够读写(订阅)个channel,一样一个channel也可被多个process读写(订阅)。

对每一个process来讲:

  • 从命名channel取出并处理消息
  • 向命名channel写入消息
  • 建立新的process

Go语言并无彻底实现CSP理论(参见知乎讨论),只提取了CSPprocesschannel的概念为并发提供理论支持。目前Go已是CSP的表明性语言。

CSP vs Actor

  • 相同的宗旨:”不要经过共享内存来通讯,而应该经过通讯来共享内存”
  • 二者都有独立的,并发执行的通讯实体
  • Actor第一类对象为执行实体(actor)CSP第一类对象为通讯介质(channel)
  • Actor中实体和通讯介质是紧耦合的,一个Actor持有一个Mailbox,而CSPprocesschannel是解耦的,没有从属关系。从这一层来讲,CSP更加灵活
  • Actor模型中actor是主体,mailbox是匿名的,CSP模型中channel是主体,process是匿名的。从这一层来讲,因为Actor不关心通讯介质,底层通讯对应用层是透明的。所以在分布式和容错方面更有优点

Go vs Erlang

  • 以上 CSP vs Actor
  • 均实现了语言级的coroutine,在阻塞时能自动让出调度资源,在可执行时从新接受调度
  • gochannel是有容量限制的,所以只能必定程度地异步(本质上仍然是同步的)erlangmailbox是无限制的(也带来了消息队列膨胀的风险),而且erlang并不保证消息是否能到达和被正确处理(但保证消息顺序),是纯粹的异步语义,actor之间作到彻底解耦,奠基其在分布式和容错方面的基础
  • erlang/otpactor上扩展了分布式(支持异质节点),热更和高容错,go在这些方面还有一段路要走(受限于channel,想要在语言级别支持分布式是比较困难的)
  • go在消息流控上要作得更好,由于channel的两个特性: 有容量限制并独立于goroutine存在。前者能够控制消息流量并反馈消息处理进度,后者让goroutine自己有更高的处理灵活性。典型的应用场景是扇入扇出,Boss-Worker等。相比goerlang进程老是被动低处理消息,若是要作流控,须要本身作消息进度反馈和队列控制,灵活性要差不少。另一个例子就是erlangreceive操做须要遍历消息队列(参考),而若是用go作同步调用,经过单独的channel来作则更优雅高效

Actor in Go

在用Go写GS框架时,不自觉地会将goroutine封装为actor来使用:

  • GS的执行实体(如玩家,公会)的逻辑具有强状态和功能聚合性,不易拆分,所以一般是一个实体一个goroutine
  • 实体接收的逻辑消息具有弱优先级,高顺序性的特色,所以一般实体只会暴露一个Channel与其它实体交互(结合go的interface{}很容易统一channel类型),这个channel称为RPC channel,它就像这个goroutine的ID,几乎全部逻辑goroutine之间经过它进行交互
  • 除此以外,实体还有一些特殊的channel,如定时器,外部命令等。实体goroutine对这些channel执行select操做,读出消息进行处理
  • 加上goroutine的状态数据以后,此时的goroutine的行为与actor类似:接收消息(多个消息源),处理消息,更新状态数据,向其它goroutine发送消息(经过RPC channel)

到目前为止,goroutine和channel解耦的优点并未体现出来,我认为主要的缘由仍然是GS执行实体的强状态性和对异步交互流程的顺序性致使的。

在研究这个问题的过程当中,发现已经有人已经用go实现了Actor模型: https://github.com/AsynkronIT/protoactor-go。 支持分布式,甚至supervisor,总体思想和用法和erlang很是像,真是有种他山逢知音的感受。:)

参考:

  1. http://jolestar.com/parallel-programming-model-thread-goroutine-actor/
  2. https://www.zhihu.com/question/26192499

 

http://wudaijun.com/2017/05/go-vs-erlang/

//--------------------------------------------------------------------------------------------- 合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。 积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以致千里;不积小流,无以成江海。骐骥一跃,不能十步;驽马十驾,功在不舍。锲而舍之,朽木不折;持之以恒,金石可镂。蚓无爪牙之利,筋骨之强,上食埃土,下饮黄泉,用心一也。蟹六跪而二螯,非蛇鳝之穴无可寄托者,用心躁也。

相关文章
相关标签/搜索