1

在以下示例中,生成的 actor 的类型为a_type,它基于typed_actor模板。如何从a_type类转换为实例A

using a_type = typed_actor<replies_to<int>::with<void>>;

class A : public a_type::base
{
protected:
    behavior_type make_behavior() override
    {
        return
        {
            [this](int value)
            {
                aout(this) << value << endl;
            }
        };
    }
};

int main()
{
    a_type spawned = spawn_typed<A>();
}
4

2 回答 2

3

Actor 是异步实体,应该被认为是独立的。虽然技术上可以通过获取原始指针actor_cast并将其向下转换为实际类型,但我强烈建议不要这样做。在 CAF 中,仅允许参与者本身访问其状态。通过消息传递解耦参与者避免了设计上的竞争条件。演员不是直接打电话给成员,而是将消息发送到其他人的邮箱。这些邮箱是真正的并发主力,并且在没有锁的情况下实现。理想情况下,您生成的actor 比可用的内核多,因为actor 应用程序通过将大问题分成许多小块来扩展,然后由许多actor 同时解决。始终牢记阿姆达尔定律:您的应用程序不能比最长的顺序处理链更快。

CAF 中的参与者句柄也启用了网络透明性。一旦你开始在网络上分发你的应用程序,直接访问状态将根本不起作用。此外,如果您使用state_based演员,从演员外部访问状态是非常不安全quit()的,因为一旦演员被调用或被杀死,状态将被销毁。

信息交换基本上有三种方式:

  • 1:1 消息传递。大多数情况下,这是正确的解决方案。scoped_actor如果您需要一种特殊的方式与演员交流,您可以随时使用。
  • N:M 使用组传递消息。这是一种将更新从任意数量的生产者推送到任意数量的订阅者的简便方法。CAF 提供命名组和“ad-hoc”匿名组以允许松散耦合的通信。
  • 共享事务(或以其他方式同步的)数据结构。如果您需要将参与者集成到现有应用程序中,或者需要将参与者与其他并发抽象结合起来,那么在参与者和非参与者之间共享并发数据结构可能是一个有效的解决方案。在此模型中,您通过其构造函数将数据结构传递给参与者。但是,在这样做之前,您应该考虑使用简单的消息传递和组(或参与者池)来组织并发工作人员的设计。这将您的应用程序限制在一台机器上,并为未来的开发占用了设计空间。

Actor 池还支持 1:N 通信(广播)、“分散/收集”式工作流程等。

在任何情况下,打破 CAF 提供的抽象通常是一个坏主意,您很快就会陷入“未定义的行为领域”。最后一点,如果您发现自己目前的设计陷入了死胡同,请随时在 CAF 邮件列表上开始讨论。

于 2015-11-20T21:06:25.947 回答
0

A可以通过首先调用actor_cast然后使用来获得类的实例dynamic_cast

int main()
{
    a_type spawned = spawn_typed<A>();
    abstract_actor* abstractActor = actor_cast<abstract_actor*, a_type>(spawned);
    A* a = dynamic_cast<A*>(abstractActor);
}
于 2015-11-20T18:34:37.780 回答