Требование: UDP-сервер, который при получении UDP-пакета сохраняет полученный пакет в одну из двух очередей. Рабочий поток связан с каждой очередью, и связанный поток получает пакет из начала очереди, обрабатывает его и записывает в систему кэширования в памяти.
Ограничения: решение должно быть основано на цикле событий (libuv) и написано на C
Мое решение
зарегистрировать обратный вызов для входящего UDP, который добавляет полученный пакет в одну из двух очередей и вызывает uv_async_send
два глобальных объекта uv_sync_t создаются по одному для каждой очереди и используются в качестве параметра для uv_async_send. Например: если пакет добавлен в очередь-1, то uv_sync_t object-1 используется как параметр для uv_async_send. Точно так же, если пакет добавляется во вторую очередь, используется uv_sync_t object-2.
запускаются два потока, каждый из которых имеет свой собственный цикл и дескриптор, связанный с обратным вызовом
- In thread-one uv_sync_t object-1 is bound against a function (say funcA). In thread-two uv_sync_t object-2 is bound against another function (say funcB)
- funcA и funcB считывают «ОДИН» пакет из соответствующей очереди и сохраняют его в кеше в памяти.
Проблема Клиент отправляет большое количество пакетов, что регистрирует большое количество событий на сервере. Теперь проблема в том, что libuv объединяет несколько вызовов в один и вызывает один обратный вызов (который удаляет ОДИН узел из очереди). Это приводит к ситуации, когда узлы добавляются в очередь с большей скоростью, а удаляются с очень низкой скоростью. Можно ли сбалансировать эти ставки?
Есть ли лучший способ спроектировать сервер, используя библиотеку событийного цикла libuv?