All streams
Search
Write a publication
Pull to refresh
82
0
Евгений Охотников @eao197

Велосипедостроитель, программист-камикадзе

Send message
2) Я правильно понял, что ответить на сообщение можно только отправив сообщение отправителю?

Есть еще и такой механизм, как синхронное взаимодействие. Агент-отправитель вместо send-а делает вызов request_value, при выполнении которого агент-отправитель блокируется. Агент-получатель получает сообщение обычным образом, как асинхронное, а возвращенное из обработчика значение будет возвращено агенту-отправителю как результат request_value. Будет что-то вроде:
class request_processor : public so_5::agent_t // Агент-получатель.
  ...
  some_result on_request(const some_request & msg ) { // обработчик события.
    ...
    return some_result(...);
  }
};
...
auto result = so_5::request_value< some_result, some_request >(
    request_processor_mbox, // Кому отсылается запрос.
    std::chrono::seconds(10), // Ждать ответа не более 10sec.
    ...); // Параметры для конструктора some_request.

Но этот способ не рекомендуется использовать без особой на то необходимости, т.к. здесь есть ряд ограничений и возможность запросто поймать дедлок.
Отвечу на каждый из вопросов в отдельном комментарии, если позволите.

1) Что с накладными расходами? Насколько медленне [или быстрее] отправить сообщение агенту, чем захватить мьютекс и вызывать метод некоторого объекта?

Накладные расходы сильно зависят от сценариев использования и от того, на каких контекстах работают взаимодействующие агенты. Например, в синтетических бенчмарках разница между простым ping-pong-ом между двумя агентами, работающими на разных нитях и на одной и той же нити, может различаться в разы: от 2M msg/sec при обмене сообщениями между разными нитями до 8-9M msg/sec при работе на одной и той же нити. Причем ping-pong — это достаточно суровый сценарий, т.к. там перед посылкой следующего сообщения нужно дождаться ответа на предыдущее. Могут быть сценарии, где сообщения поступают к агентам пачками, там можно и еще большие числа получить (вот, например).

В принципе, мутекс (а тем более спинлок) с последующим вызовом метода объекта должны быть быстрее. Но когда у вас задача не настолько сложная, чтобы запутаться в мутексах, то вам и инструменты вроде SObjectizer не нужны. А когда настолько сложная, что возня с мутексами сильно замедляет саму разработку, то вы упрощаете себе жизнь за счет асинхронного взаимодействия, но ценой увеличения накладных расходов.
Но и здесь все не так однозначно, т.к. на мутексах вполне можно получить голодание рабочих нитей, когда они взаимно блокируются и ждут какого-то одного мутекса.
12 ...
92

Information

Rating
6,217-th
Location
Гомель, Гомельская обл., Беларусь
Registered
Activity