Actor 模型 / CSP 模型 / 共享内存模型
CSP 模型 通信顺序进程,其实就是基于 channel 的消息通信,在 ROS 中,这种 channel 称作主题 topic
erlang 是 actor 的代表性语言,go 是 CSP 的代表性语言
还有几个没怎么看的答案,不过都差不多了,这个讲历史比较多,也比较透彻,很有用,需要再仔细看!
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,可以使用在 Linux,Windows,Mac,ARM 和 Matlab 环境。
我们知道面向对象编程中使用的是 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/Erlang 的 actor 模型与 Go 语言的协程 Goroutine 与通道 Channel 代表的 CSP(Communicating Sequential Processes) 模型有什么区别呢?
首先这两者都是并发模型的解决方案,我们看看 Actor 和 Channel 这两个方案的不同:
Actor 模型
在 Actor 模型中,主角是 Actor,类似一种 worker,Actor 彼此之间直接发送消息,不需要经过什么中介,消息是异步发送和处理的:
Actor 模型描述了一组为了避免并发编程的常见问题的公理:
1. 所有 Actor 状态是 Actor 本地的,外部无法访问。
2.Actor 必须只有通过消息传递进行通信。
3. 一个 Actor 可以响应消息: 推出新 Actor, 改变其内部状态, 或将消息发送到一个或多个其他参与者。
4.Actor 可能会堵塞自己, 但 Actor 不应该堵塞它运行的线程。
更多可见 Actor 模型专题
Channel 模型
Channel 模型中,worker 之间不直接彼此联系,而是通过不同 channel 进行消息发布和侦听。消息的发送者和接收者之间通过 Channel 松耦合,发送者不知道自己消息被哪个接收者消费了,接收者也不知道是哪个发送者发送的消息。
Go 语言的 CSP 模型是由协程 Goroutine 与通道 Channel 实现:
Actor 模型和 CSP 区别
Actor 模型和 CSP 区别图如下:
Actor 之间直接通讯,而 CSP 是通过 Channel 通讯,在耦合度上两者是有区别的,后者更加松耦合。
同时,它们都是描述独立的流程通过消息传递进行通信。主要的区别在于:在 CSP 消息交换是同步的 (即两个流程的执行 "接触点" 的,在此他们交换消息),而 Actor 模型是完全解耦的,可以在任意的时间将消息发送给任何未经证实的接受者。由于 Actor 享有更大的相互独立, 因为他可以根据自己的状态选择处理哪个传入消息。自主性更大些。
在 Go 语言中为了不堵塞流程,程序员必须检查不同的传入消息,以便预见确保正确的顺序。CSP 好处是 Channel 不需要缓冲消息,而 Actor 理论上需要一个无限大小的邮箱作为消息缓冲。
https://www.cnblogs.com/feng9exe/p/10482436.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 模型上,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 来说:
Go 语言并没有完全实现 CSP 理论 (参见知乎讨论),只提取了 CSP 的 process 和 channel 的概念为并发提供理论支持。目前 Go 已经是 CSP 的代表性语言。
CSP vs Actor
Go vs Erlang
Actor in Go
在用 Go 写 GS 框架时,不自觉地会将 goroutine 封装为 actor 来使用:
到目前为止,goroutine 和 channel 解耦的优势并未体现出来,我认为主要的原因仍然是 GS 执行实体的强状态性和对异步交互流程的顺序性导致的。
在研究这个问题的过程中,发现已经有人已经用 go 实现了 Actor 模型: https://github.com/AsynkronIT/protoactor-go。 支持分布式,甚至 supervisor,整体思想和用法和 erlang 非常像,真是有种他山逢知音的感觉。:)
参考:
原文:https://www.cnblogs.com/cx2016/p/14083636.html