首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >阿克卡“演员”与“二郎”中的信息顺序语义的后果

阿克卡“演员”与“二郎”中的信息顺序语义的后果
EN

Stack Overflow用户
提问于 2014-12-11 14:35:25
回答 3查看 564关注 0票数 2

从课件上的反应性编程的类原理来看:

“如果一个参与者向同一个目的地发送多条消息,它们就不会出现故障(这是Akka特有的)。”

行动者A和B

A发送B msg1 A发送B msg2

B将接收msg1,然后接收msg2

警告:我从来没有在Erlang编程

我认为这种消息排序语义在Erlang中没有得到保证。这似乎是一个巨大的差异,它影响了您可以使用类似框架编写的不同类型的程序。

例如,在Akka,您可以这样做:

代码语言:javascript
复制
case class msg(x: Int)
case object report
class B extends Actor {

var i: Int = 0
def recieve = {
    case msg(x) => i = i + x
    case report => sender ! i
 }
}

那你就可以

发送B(5)

发送B(6)

A发送B报告//保证金额为11

我的主要观点是,Erlang似乎无法保证返回的金额为11。Erlang是否劝阻甚至禁止行为者包含任何可变状态?有谁能详细说明在Scala的Akka vs.中用Actors编写的不同类型的程序吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-12-11 16:20:57

正如Pascal所说,两个进程之间的消息顺序得到了保证。在Erlang,拥有某种“可变状态”的唯一方法是将其隐藏在演员的后面。通常是这样做的:

代码语言:javascript
复制
loop(Sum) ->
    NewSum = receive Message of
        {msg, Number, Sender} -> add_and_reply(Sum, Number, Sender);
        _ -> Sum
    end,
    loop(NewSum).

add_and_reply(Sum, Number, Sender) ->
    NewSum = Sum + Number,
    Sender ! NewSum,
    NewSum.

这样你就不会变异任何东西。您将创建新状态并将其作为一个参数传递给无休止的递归。运行循环的参与者确保所有调用都是一个接一个地服务的,因为它一次只接受一条消息。

对我来说,Erlang和Akka的主要区别是先发制人的调度。在Erlang中,您可以编写这样的演员:

代码语言:javascript
复制
loop(Foo) ->
    something_processor_consuming(),
    loop(Foo).

你的系统就能工作了。大多数由库添加参与者的语言都会转到这个线程中,并且它将永远阻止一个CPU内核的执行。Erlang能够停止这个线程,运行其他的东西并返回到它,所以它很好地发挥,即使你搞砸了。在这里读更多。在Erlang中,您可以从exit(Pid, kill)外部终止进程,它将立即终止。在Akka中,它将继续处理,直到为下一条消息做好准备(您可以使用trap_exit标志来模拟Erlang )。

从一开始就有Erlang是建立在容错和软实时系统的基础上的。,所以OTP强调监督过程。例如,在Scala中,主管有机会在错误时恢复子级,而在Erlang中,子级在出错时崩溃,并且必须重新启动。这是因为假设,崩溃意味着坏的状态,我们不想传播它。

票数 4
EN

Stack Overflow用户

发布于 2014-12-11 15:03:38

答案是肯定的,这是保证的:查看常见问题 (它不是显式写入的,但以已知顺序发送消息的唯一方法是从相同的进程发送消息)

代码语言:javascript
复制
10.8  Is the order of message reception guaranteed?

Yes, but only within one process.

If there is a live process and you send it message A and then message B, it's guaranteed that if message B arrived, message A arrived before it.

On the other hand, imagine processes P, Q and R. P sends message A to Q, and then message B to R. There is no guarantee that A arrives before B. (Distributed Erlang would have a pretty tough time if this was required!)
票数 4
EN

Stack Overflow用户

发布于 2014-12-11 21:53:28

是的,您可以保证这种情况-- "Erlang消息“并不意味着”简单的UDP“。

A可以发送B "1,2,3,4,5“,它将按该顺序准确地得到"1,2,3,4,5”,而不管A和B在集群中的位置-考虑该语句最后部分的含义。

不能保证的是,从C到B的顺序消息"a,b,c,d,e“将相对于A的并发消息流的可能交织而到达B。"1,2,a,b,c,3,4,5,d,e“可能与"1,2,3,4,5,a,b,c,d,e”或两条独立有序的消息流的任何其他交织。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27425312

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档