Перенос ремесленных систем в libcaf

В настоящее время у меня есть приложение, в котором используются актеры ручной работы. Мой план состоит в том, чтобы портировать его на libcaf.

Текущее состояние таково: у меня есть одна большая глобальная очередь сообщений, в которой мои системы (так называемые акторы) подписываются на получение своих сообщений. Они отвечают сообщениями в эту глобальную очередь.

Вся система представляет собой приложение реального времени, работающее на ядре Linux rt-preempt. Поток GUI сам по себе является системой (актером), но не имеет приоритета RT.

Прямо сейчас моим системам не нужно знать получателей их сообщений, потому что получатели регистрируются на тех, кого они хотят.

Моя идея переноса такова: я использую одного глобального актера в качестве замены моей глобальной очереди сообщений, и он обрабатывает регистрацию сообщений. Таким образом, я могу получить простой журнал сообщений для целей отладки, и мне не нужно, чтобы все участники знали все возможные цели.

У меня есть система ввода-вывода (canbus), которая обрабатывает контакт с реальным миром.

В моей текущей системе я создаю поток GUI + system. Он ожидает инициализации RT. После того, как поток графического интерфейса создан, я переключаюсь на приоритет RT Preempt и создаю другие системы, prefault стек и так далее. Когда все настроено, я уведомляю графический интерфейс о том, что RT работает. Теперь моя система инициализирована.

Когда происходят какие-то фатальные события или система должна быть отключена, я отправляю сообщение, и все системы отключаются, и все потоки объединяются.

Мои вопросы: как я могу отделить актора/поток GUI от потока RT в libcaf? Вы бы порекомендовали разветвить графический интерфейс в отдельном процессе? Могу ли я создавать актеров в потоках с другим приоритетом RT?

РЕДАКТИРОВАТЬ: я нахожу вариант spawn detached. Находятся ли порожденные актеры (потомки отдельного актера) в одном потоке?


person schorsch_76    schedule 25.04.2016    source источник


Ответы (1)


Текущее состояние таково: у меня есть одна большая глобальная очередь сообщений, в которой мои системы (так называемые акторы) подписываются на получение своих сообщений. Они отвечают сообщениями в эту глобальную очередь.

Прямо сейчас моим системам не нужно знать получателей их сообщений, потому что получатели регистрируются на тех, кого они хотят.

У CAF есть группы публикации/подписки, которые, кажется, хорошо подходят для этого. Потребители просто присоединяются к известной группе, а производители отправляются в нее. Это дает вам именно ту развязку отправителей и получателей, которую вы ищете.

Когда происходят какие-то фатальные события или система должна быть отключена, я отправляю сообщение, и все системы отключаются, и все потоки объединяются.

Есть два способа легко добиться этого. Один из них — использовать группу, но для этого требуется, чтобы все ваши действующие лица были подписаны на нее при обнаружении фатального состояния системы. В качестве альтернативы вы можете использовать одного корневого актора для порождения всех других акторов и всегда использовать флаг linked во время порождения. Таким образом, убийство корневого актора будет рекурсивно убивать его потомков.

Как я могу отделить актора/поток GUI от потока RT в libcaf? Вы бы порекомендовали разветвить графический интерфейс в отдельном процессе?

В версии 0.14 вам придется переместить графический интерфейс в отдельный процесс, а затем подключиться к нему через remote_actor. В качестве побочного эффекта это отделяет графический интерфейс от логики приложения, и сбои в графическом интерфейсе не влияют на другие части вашей системы. Конечно, в этом сценарии вы платите за локальную связь и сериализацию.

В грядущей версии 0.15 вы также можете использовать разные экземпляры actor_system с отдельными планировщиками. Это может сэкономить вам немного накладных расходов, но я все же предпочел бы переместить графический интерфейс в свой собственный процесс.

Кстати, вам не обязательно использовать fork. Вы можете просто запустить свое приложение, publish одного актера к порту, а затем подключить свой графический интерфейс через remote_actor.

Я считаю, что опция спавна отключена. Находятся ли порожденные актеры (потомки отдельного актера) в одном потоке?

Отсоединенный актор всегда будет работать в своем собственном потоке.

Могу ли я создавать актеров в потоках с другим приоритетом RT?

Краткий ответ: нет. CAF использует интерфейс std::thread, который является переносимым, но просто не поддерживает приоритеты RT. Добавление флагов приоритета при отсоединении актеров возможно, но подобные функции для конкретных платформ не входят в наш список задач.

При этом мы, конечно же, будем принимать исправления для CAF, которые добавляют поддержку приоритета RT.

person neverlord    schedule 26.04.2016
comment
Спасибо за ваш развернутый ответ! Я собираюсь написать доказательство концепции. Об атрибутах потока: в основном это просто sched_setscheduler и mlockall, которые нужно вызывать в потоке RT один раз. Так что я думаю, что добавить в libcaf особо нечего. - person schorsch_76; 26.04.2016