Если шаблон проектирования Proactor лучше подходит для асинхронного ввода-вывода, почему он не используется по умолчанию в ASIO? - PullRequest
0 голосов
/ 21 февраля 2019

В последнее время я довольно сильно запутался в обзоре кода, внедрив сокет ASIO UDP в интерфейсный адаптер;Похоже, был реализован еще один входной сокет UDP, и предполагалось, что и вход, и выход находятся в одном потоке.Итак, мне интересно, почему библиотеки сокетов ASIO не поддерживают статический поток (контекст сокета) и используют его для каждого сокета?Какова мотивация и компромиссы, которые следует учитывать при использовании шаблона Proactor?

Редактировать / Дополнение

После того, как некоторые комментарии о моих вопросах были неясны,Я добавляю этот фрагмент кода, основываясь на определении класса, которое, как мне сказали, не соответствует шаблону Proactor:

class InterfaceAdapter{
  public:
    typedef std::vector<MsgFragment> MsgPackets;
    InterfaceAdapter() :
      mySocket(myContext) {}
    void sendDataToSystem(const DataStruct& originalData);
  private:
    asio::io_context myContext;
    asio::ip::udp::socket mySocket;
    MsgPackets transformData(const DataStruct& originalData);
    void sendPackets(const MsgPackets& msgs);
};

Очевидно, мне нужно было использовать глобальную область действия asio::io_context вместо того, чтобы использовать его какзакрытый член и использовать его для создания сокета по умолчанию?

1 Ответ

0 голосов
/ 21 февраля 2019

Ваши вопросы не совсем понятны, и что-то смешанное или подразумеваемое, и я предполагаю, что это также является причиной вашей проблемы:

Повышение ASIO - это шаблон проактора, асинхронные обработчики выполняются, как правило, после завершениядругой обработчик т.е. обратный вызов.Это можно сделать одновременно, если пользователь выберет это, запустив boost::asio::io_context::run в более чем 1 потоке.

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

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

Приложение к вашему приложению: Нет, я не должен быть глобальным, я предполагаю, что рецензенты утверждают, что у вас есть свой собственный asio::io_context, который вам обычно не нужен, потому что ваш класс, похоже, только отправляет пакеты, поэтому для него должно быть безразлично, на каком io_context он выполняется.По этой причине буст-сокеты и прочие просто принимают ссылку на io_context, я делаю это сам, например, RTP-класс, который я написал .Там вы можете видеть, что я просто храню ссылку на io_context, которой управляет весь сервер RTSP Videostreaming.

Однако я боюсь, что ваша компания / рецензент не использует boost asio, иначе ваш адаптер может быть первымиспользование boost asio внутреннее, но не предназначено для утечки этой детали реализации.Тогда это зависит от того, как используется ваш класс: будет ли обычно только один экземпляр за все время жизни программы, , например ?Тогда он может управлять своим собственным io_context, но я предполагаю, что вы скорее создадите несколько его экземпляров.Представьте себе улучшенное tcp-соединение, то есть создающее потоки сокетов, и все для себя, для каждого tcp-соединения, которое имеет сервер, это было бы глупо.

Таким образом, решение в этом случае будет либо просто взять io_context& в вашем конструкторе, либо, если затем вы хотите избежать детализации буста, другой класс, разработанный вами, который должен сохранить создатель InterfaceAdapterи повторно использует каждый раз, когда он создает новый интерфейсный адаптер.Однако, если это не возможно, чем вы действительно должны провести рефакторинг всей вашей программы, но это будет момент, когда посредственные люди начнут использовать глобальные переменные.Но тогда не делайте ваш InterfaceAdapter или boost::io_context глобальным, а что-то вроде class my_io_singleton, которое все еще должно быть передано в ваш InterfaceAdpater, так что в один прекрасный день ваш код будет легко реорганизован.

Обновление 2 Следующая вещь может снова вас отключить, поэтому я советую вам прочитать ее только после прочтения вышеупомянутой части и после того, как вы проделали еще какую-то реализацию с boost asio, поскольку это не очень важно идля вашего случая: если честно, есть редкие случаи, когда boost io_contexts кажется синглтоноподобным, Я наткнулся на себя , но это всего лишь функции комфорта, встроенные в asio, о которых можно поспоритьможет быть лучше оставить в стороне.Но их можно просто игнорировать.

...