Как получить доступ к вновь созданному экземпляру типа T после вызова spawn_typed & lt; T & gt; (…)? (C ++ Actor Framework)

В следующем примере порожденный актер имеет тип 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>();
}

1

Решение

Актеры являются асинхронными объектами и должны рассматриваться как изолированные. Хотя технически возможно получить необработанный указатель через actor_cast и принизить его до фактического типа, я настоятельно рекомендую не делать этого. Только сам актер имеет доступ к своему состоянию в CAF. Разделение актеров с помощью передачи сообщений позволяет избежать условий гонки по дизайну. Вместо непосредственного вызова участников актеры отправляют сообщения в почтовые ящики других пользователей. Эти почтовые ящики являются настоящими рабочими лошадками для параллелизма и реализованы без блокировок. В идеале вы порождаете больше актеров, чем доступно ядер, так как приложения актеров масштабируются, разбивая большие проблемы на множество маленьких кусков, которые затем решаются множеством актеров одновременно. Всегда помните закон Амдаля: ваше приложение не может быть быстрее, чем ваша самая длинная цепочка последовательной обработки.

Дескрипторы актера в CAF также обеспечивают прозрачность сети. Как только вы начнете распространять свое приложение по сети, прямой доступ к состоянию просто не будет работать. Далее, если вы используете state_based актеры, доступ к государству со стороны актера крайне небезопасно, потому что государство будет уничтожено, как только актер вызвал quit() или был убит.

Существует три основных способа обмена информацией:

  • Передача сообщений 1: 1. Это правильное решение большую часть времени. Вы всегда можете использовать scoped_actor если вам нужен специальный способ общения с актером.
  • N: M передача сообщений с использованием групп. Это простой и удобный способ передавать обновления от любого количества производителей любому количеству подписчиков. CAF предлагает как именованные группы, так и «специальные» анонимные группы, чтобы разрешить слабосвязанное общение.
  • Совместное использование транзакционных (или иным образом синхронизированных) структур данных. Если вам нужно интегрировать акторы в существующее приложение или вам нужно объединить акторы с другими абстракциями параллелизма, разделяя параллельные структуры данных между акторами и неакторами Можно быть верным решением. В этой модели вы передаете структуру данных субъекту через его конструктор. Однако, прежде чем сделать это, вы должны рассмотреть проект с простой передачей сообщений и группами (или пулами актеров), чтобы сначала организовать параллельных работников. Это ограничивает ваше приложение одной машиной и отнимает пространство для разработки для будущих разработок.

Пулы актеров также обеспечивают рабочие процессы в стиле 1: N (широковещание), «разброс / сбор» и т. Д.

В любом случае нарушение абстракции, предоставляемой CAF, обычно является плохой идеей, и вы можете очень быстро оказаться в «неопределенной зоне поведения». И последнее замечание: если вы оказались в тупике с вашим текущим дизайном, пожалуйста, не стесняйтесь начинать обсуждение в списке рассылки CAF.

3

Другие решения

Экземпляр класса 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);
}
0

По вопросам рекламы [email protected]