C HTTP-сервер - многопоточная модель? - PullRequest
4 голосов
/ 16 апреля 2011

В настоящее время я пишу HTTP-сервер на C, чтобы узнать о C, сетевом программировании и HTTP.Я реализовал большинство простых вещей, но я обрабатываю только одно соединение за раз.В настоящее время я думаю о том, как эффективно добавить многозадачность в мой проект.Вот некоторые варианты, о которых я подумал:

  1. Использовать один поток на соединение.Просто, но не может обрабатывать много соединений.
  2. Используйте только неблокирующие вызовы API и обрабатывайте все в одном потоке.Звучит интересно, но использование select() s и такое чрезмерное называется довольно медленным.
  3. Некоторая другая модель многопоточности, например, такая сложная, как lighttpd .(Возможно) лучшее решение, но (вероятно) слишком сложное для реализации.

Есть мысли по этому поводу?

Ответы [ 5 ]

4 голосов
/ 16 апреля 2011

Не существует единственной лучшей модели для написания многозадачных сетевых серверов.Разные платформы имеют разные решения для высокой производительности (порты завершения ввода / вывода, epoll, kqueues).Будьте осторожны при достижении максимальной переносимости: некоторые функции имитируются на других платформах (т. Е. select() доступна в Windows) и дают очень низкую производительность, поскольку они просто отображаются на какую-то другую собственную модель.

Кроме того, естьдругие модели не включены в ваш списокВ частности, классическая UNIX-модель "pre-fork".

Во всех случаях используйте любую форму асинхронного ввода-вывода, если она доступна.Если это не так, обратите внимание на неблокирующие синхронные операции ввода-вывода.Создайте свою HTTP-библиотеку на основе асинхронной потоковой передачи данных, но не используйте бит ввода-вывода.Это намного сложнее, чем кажется.Обычно это подразумевает написание конечных автоматов для вашего интерпретатора протокола.

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

4 голосов
/ 16 апреля 2011

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

2 голосов
/ 16 апреля 2011

Вы можете использовать цикл событий, как в файле node.js:

Исходный код узла (c, c ++, javascript)

https://github.com/joyent/node

Райан Даль (создатель узла) обрисовывает в общих чертах обоснование дизайна node.js, неблокирующего ввода-вывода и цикла событий как альтернативы многопоточности в веб-сервере.

http://www.yuiblog.com/blog/2010/05/20/video-dahl/

Дуглас Крокфорд обсуждает цикл событий в сцене 6: Loopage (пятница, 27 августа 2010 г.)

http://www.yuiblog.com/blog/2010/08/30/yui-theater-douglas-crockford-crockford-on-javascript-scene-6-loopage-52-min/

Указатель вышеприведенного выступления Дугласа Крокфорда (если необходима дополнительная справочная информация).Правда, к вашему вопросу это не относится.

http://yuiblog.com/crockford/

0 голосов
/ 16 апреля 2011

Простое решение может состоять из нескольких процессов: один процесс принимает соединения, и как только соединение установлено fork и обрабатывает соединение в этом дочернем процессе.

Интересный вариант этого методаиспользуется прокси-сервером SER / OpenSER / Kamailio SIP: есть один основной процесс, который принимает соединения и несколько дочерних рабочих процессов, связанных через каналы.Родитель отправляет новый дескриптор файла через сокет.См. выдержку из этой книги в 17.4.2.Передача файловых дескрипторов через доменные сокеты UNIX .SIP-прокси OpenSER / Kamailio используются для сверхпрочной обработки SIP, где производительность является огромной проблемой, и они очень хорошо справляются с этой техникой (плюс общая память для обмена информацией).Тем не менее, многопоточность проще реализовать.

0 голосов
/ 16 апреля 2011

Посмотрите на вашей самой эффективной модели опроса сокетов - epoll (linux), kqueue (freebsd), WSAEventSelect (Windows).Возможно объединить с пулом потоков, обработать N соединений на поток.Вы всегда можете начать с select, а затем заменить его на более эффективную модель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...