.. моя идея заключается в следующем: создать несколько потоков с собственным epoll
дескрипторы, основной поток принимает соединения и распределяет их
среди тем эполл.
Да, в настоящее время это лучший способ сделать это, и именно так Nginx это делает. Количество потоков может быть увеличено или уменьшено в зависимости от нагрузки и / или количества физических ядер на машине.
Компромисс между дополнительными потоками (больше, чем количество физических ядер) и событиями заключается в задержке и пропускной способности. Потоки улучшают задержку, потому что они могут выполняться преимущественно, но за счет пропускной способности из-за накладных расходов, связанных с переключением контекста и созданием / удалением потока. События улучшают пропускную способность, но имеют тот недостаток, что длительный код приводит к остановке всего потока.
Второй лучший способ - это то, как Apache2 делает это, используя пул потоков блокирующих потоков. Здесь нет обработки событий, поэтому реализация проще, и пул означает, что потоки не создаются и не уничтожаются без необходимости, но он не может реально конкурировать с хорошо реализованным потоково-асинхронным гибридом, таким как то, что вы пытаетесь реализовать, или Nginx.
Третий лучший вариант - это только асинхронная обработка событий, например Lighttpd или Node.js. Ну, это второй вариант, если вы не выполняете тяжелую обработку на сервере. Но, как упоминалось ранее, один длительный цикл while блокирует весь сервер.