Многопоточность сервера, обязательная для протокола?и больше - PullRequest
0 голосов
/ 29 января 2010

Предположим, протокол уровня приложения реализован через UDP. Требуется тайм-аут клиента, поэтому серверу необходимо сохранять состояние каждого клиента, с которым он обращается.

Также предположим, что используется select.

  1. Всегда ли лучше реализовывать многопоточный сервер? Я полагаю, что список ссылок будет делать то же самое, где время ожидания сервера time=Earliest Timeout of a client- CurrentTime. Список ссылок будет иметь ту же функцию, что и сохранение состояний клиента, при этом избегая накладных расходов на создание новых потоков (хотя и усложняет работу сервера по поддержанию времени ожидания конкретного клиента).

  2. Если выбрана многопоточность, то лучше ли будет вызывать новый сокет для нового клиента? Это приведет к дополнительным системным ресурсам. Но я полагаю, что сокет сервера по умолчанию (bind с общеизвестным портом сервера) будет делать то же самое, поскольку он получил буфер (ну ... может быть недостаточно для масштабируемого числа клиентов ..)

Спасибо!

Ответы [ 4 ]

2 голосов
/ 29 января 2010

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

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

  • Это делает взаимодействие с переменным состоянием намного более управляемым, поэтому предсказуемым, что означает, что многопоточность является более устойчивой.
  • Если все сделано правильно, он может максимально использовать число процессоров, которые есть у вашего процессора.
  • Позволяет вам напрямую контролировать приоритет, который вы хотите отдать определенным функциям - если эта функция имеет высокий приоритет, вы отправляете ее в поток с высоким приоритетом, затем, когда она завершается, она отправляет результаты обратно на низкий приоритет вызывающего абонента через продолжение в потоке вызывающего абонента. Или в другой теме - нет причин ограничивать это.
  • Часто возможно портировать в непоточные среды. Может быть, не важно для большинства, но иногда важно для меня.
1 голос
/ 29 января 2010

Я не собираюсь предлагать что-то новое, чего нет в ответе Эйдана Калли, однако, взглянем на теорию, лежащую в основе многопроцессорных модулей Apache:По сути, сервер разделен на несколько модулей, и для управления соединениями создаются потоки / процессы, в зависимости от необходимости и параметров конфигурации - похоже, баланс описан в ответе Эйдана, хотя реализация Apache может немного отличаться.

0 голосов
/ 29 января 2010

Связанные списки не будут масштабироваться.

Использование связанных списков на стороне сервера для проверки клиентов по одному и удовлетворения их потребностей - это хорошо для 5-10 клиентов. Но что происходит, когда у вас есть 100? 1000? Что произойдет, если один запрос клиента займет очень много времени?

Потоки не просто предоставляют способ поддерживать состояние для отдельных клиентов. Они также предоставляют способ одновременного «распределения ресурсов сервера» по всем клиентам. Это как если бы у каждого клиента был выделенный сервер, очереди (почти) нет: клиент чего-то хочет, он запрашивает сервер, сервер отвечает. Это мгновенно.

Кроме того, вы могли бы тратить ценные ресурсы с помощью подхода с использованием связанного списка. Что делать, если все клиенты, кроме одного, ничего не хотят? Вы будете многократно повторять циклы для более чем ста клиентов, ничего не делая, кроме как тратить циклы ЦП, пока не встретите того, который требует , требует внимания сервера.

0 голосов
/ 29 января 2010

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

Да, добавление нового потока / сокета для каждого соединения потребляет больше ресурсов. Похоже, вам нужно определить, сколько соединений вам понадобится. Затем вы можете определить, будете ли у вас достаточно ресурсов или нет.

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

...