C: epoll и многопоточность - PullRequest
       20

C: epoll и многопоточность

12 голосов
/ 14 января 2011

Мне нужно создать специализированный HTTP-сервер, для этого я планирую использовать epoll sycall, но я хочу использовать несколько процессоров / ядер и не могу придумать архитектурное решение. Моя идея заключается в следующем: создать несколько потоков с собственными дескрипторами epoll, основной поток принимает соединения и распределяет их по потокам epoll. Но есть ли лучшие решения? Какие книги / статьи / руководства я могу прочитать на архитектурах с высокой нагрузкой? Я видел только C10K статью, но большинство ссылок на примеры мертвы :( и по-прежнему нет подробных книг на эту тему: (.

Спасибо за ответы.

UPD: Пожалуйста, будьте более конкретны, мне нужны материалы и примеры (nginx не является примером, потому что он слишком сложен и имеет несколько уровней абстракции для поддержки нескольких систем).

Ответы [ 3 ]

12 голосов
/ 14 января 2011

.. моя идея заключается в следующем: создать несколько потоков с собственным epoll дескрипторы, основной поток принимает соединения и распределяет их среди тем эполл.

Да, в настоящее время это лучший способ сделать это, и именно так Nginx это делает. Количество потоков может быть увеличено или уменьшено в зависимости от нагрузки и / или количества физических ядер на машине.

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

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

Третий лучший вариант - это только асинхронная обработка событий, например Lighttpd или Node.js. Ну, это второй вариант, если вы не выполняете тяжелую обработку на сервере. Но, как упоминалось ранее, один длительный цикл while блокирует весь сервер.

11 голосов
/ 14 января 2011

проверка libevent и libev источников. они хорошо читаются и уже являются хорошей инфраструктурой для использования.

Кроме того, документация libev содержит множество примеров нескольких проверенных и верных стратегий. Даже если вы предпочитаете писать напрямую в epoll(), примеры могут привести к нескольким выводам.

0 голосов
/ 14 января 2011

Если у вас нет терабитного канала связи и вы планируете обслуживать 10000 одновременных соединений с одного сервера, забудьте о epoll. Это просто безвозмездная непереносимость; poll или даже select будет так же хорошо. Имейте в виду, что к тому времени, когда терабитные и другие ссылки станут стандартными, ваш сервер также будет работать достаточно быстро, и вам все равно не понадобится epoll.

Если вы просто обслуживаете статический контент, забудьте также о потоках и используйте системный вызов Linux sendfile. Это тоже нестандартно, но, по крайней мере, дает огромные преимущества в производительности.

Также обратите внимание, что другие проектные решения (особенно избыточная сложность) будут намного больше влиять на то, сколько нагрузки может выдержать ваш сервер. В качестве примера, просто посмотрите, как скромный однопоточный однопроцессный thttpd поражает Apache и его друзей в производительности со статическим контентом - и по моему опыту даже с традиционным динамическим контентом cgi!

...