Лучшая практика для создания сервера - корутины или poll / select

Добрый день, коллеги.

Возможно, вы уже видели данный пост уже есть на stackoverflow .ru, но та площадка плохо подходит для активного обсуждения, если оно завяжется.

Некоторое время писал разное прикладное клиент-серверное ПО на C++ по линуксовые ОС. Моя обычная практика (в общих чертах):

  1. создать "серверный" сокет для приема входящих подключений

  2. тем или иным образом "отметить" его как "серверный"

  3. написать фрагмент кода/функцию приема входящих подключений (1)

  4. написать фрагмент кода/функцию обслуживающий принятые подключения (клиентов) (2)

  5. написать фрагмент кода/функцию обслуживающий таймаут ожидания (3)

  6. завести массив / вектор для файл-дескрипторов

  7. запустить select / poll для этого массива

  8. при наступлении какого либо события (1),(2) или (3) - дернуть соответствующую функцию.

В принципе, для не сильно нагруженных приложений всегда хватало такого подхода. Корутины C++ для этого не использовал в основном потому, что они в этом языке неудобные (мнение субъективное). Однако прочитал я про замечательные примеры корутин в Go и, соответственно, примеры реализации клиент-серверных приложений на этих корутинах (ибо там они очень удобно выглядят). Как я понял, в общих чертах подход следующий:

  1. создать "серверный" сокет для приема входящих подключений

  2. написать функцию-корутину приема входящих подключений (1)

  3. написать функцию-корутину обслуживающую принятые подключения (клиентов) (2)

  4. на каждого из принятых клиентов заводить "свою" корутину

  5. корутины "сами дергаются" при наступлении события

Данный подход я практически полностью переписал с примера "кричащий сервер на go", как я его увидел и понял. В данном случае вообще не важно что там под капотом, особенно если смотреть с верхнего уровня.

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

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

Предлагаю высказать свои соображения по этому поводу или собственный опыт.

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

Считается, что корутины это не альтернатива поллингу, но в достаточном количестве примеров выглядит как буд-то это так.

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

Лига программистов

1.5K постов11.4K подписчиков

Добавить пост

Правила сообщества

- Будьте взаимовежливы, аргументируйте критику

- Приветствуются любые посты по тематике программирования

- Если ваш пост содержит ссылки на внешние ресурсы - он должен быть самодостаточным. Вариации на тему "далее читайте в моей телеге" будут удаляться из сообщества