46

什么时候应该使用Actor 模型

它当然不能保证无死锁的环境。

演员 A 可以等待 B 的消息,而 B 等待 A。

此外,如果参与者必须确保其消息在继续执行下一个任务之前已得到处理,则它必须发送消息并等待“您的消息已处理”消息,而不是直接阻塞。

模型的力量是什么?

4

4 回答 4

30

考虑到一些并发问题,你会寻找什么来决定是否使用演员?

首先,我想定义问题……主要动机是加速嵌套 for 循环还是递归?如果是这样,一个简单的基于任务的方法或并行循环方法可能对您(而不是参与者)很有效。

但是,如果您有一个涉及依赖关系和协调共享状态的更复杂的系统,那么参与者方法可以提供帮助。特别是通过使用参与者和消息传递语义,您通常可以通过实际复制该状态(消息)并对它们做出反应来避免使用显式锁来保护共享状态。

你可以用经典的同步问题很容易做到这一点,比如哲学家进餐和睡觉的理发师问题。但是你也可以使用'actor'来帮助更现代的模式,即你的外观可以是一个actor,你的模型视图和控制器也可以是相互通信的actor。

我观察到的另一件事是,大多数开发人员都可以学习参与者语义,并且比锁定的同行“更安全”。这是因为它们提高了抽象级别并允许您专注于协调对该数据的访问,而不是使用锁保护对数据的所有访问。例如,假设您有一个带有数据成员的简单类。如果您选择在该类中放置一个锁以保护对该数据成员的访问,那么该类上的任何方法都需要确保它们正在访问该锁下的该数据成员。当其他人(或您)在以后修改该类时,这变得特别成问题,他们必须记住使用该锁。

另一方面,如果该类成为参与者并且数据成员成为您通过消息与之通信的缓冲区或端口,则您不必记住锁定,因为语义是内置在缓冲区中的,您将非常明确地知道您是否要根据缓冲区的类型阻止它。

-瑞克

于 2009-11-29T01:04:02.310 回答
24

Actor 的使用至少在两种情况下是“自然的”:

  1. 当您可以将问题分解为一组独立的任务时。
  2. 当您可以通过明确的工作流程(即数据流编程)链接的一组任务中分解您的问题时。

例如,如果您使用一系列过滤器处理复杂数据,则很容易使用参与者管道,其中每个参与者从上游参与者接收数据并将数据设置给下游参与者。

当然,这个数据流不能是线性的,如果你的管道中的一个步骤很慢,你可以使用一个演员池来做同样的工作。解决负载平衡问题的另一种方法是使用一种由一种虚拟看板系统组织的需求驱动方法。

当然,在几乎所有有趣的情况下,您都需要演员之间的同步,但与经典的多线程方法相反,这种同步确实是“具体的”。你可以想象一个工厂里的人,想象可能出现的问题(工人没有工作要做,上游操作太快,中间产品需要一个巨大的存储空间等)。以此类推,你可以更容易地找到解决方案。

于 2009-11-29T08:00:31.103 回答
2

我不是演员专家,但这是我何时使用演员模型的 2 美分:演员模型并不适合每个并发应用程序,例如,如果您正在创建一个多线程并在高并发下工作的应用程序,则演员模型不是解决并发问题。当你创建一个事件驱动的应用程序时,actor 真正发挥作用的地方。例如,您有一个应用程序,并且您正在跟踪用户在您的应用程序中实时点击的内容。由于参与者是有状态的,因此您可以使用参与者执行按用户、设备或任何业务需求实时隔离的活动。因此,例如,如果某些用户位于点击的演员中shirts您可以向他们发送一些优惠券的通知。演员派上用场的一些应用还有:金融(定价、欺诈检测)、多人游戏。

于 2020-05-21T02:57:45.437 回答
1

参与者是异步和并发的,但不保证消息的顺序或时间限制,即何时可以对消息采取行动。因此,原子事务不能拆分为 Actor。

如果应用程序/任务不涉及可变状态,那么由于 Actor 框架竭尽全力避免竞争条件,Actor 就显得过分了。

于 2019-02-05T05:21:12.900 回答