Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > Рецепт правильного сервера с т. зрения потоков


Автор: leniviy 1.11.2010, 17:17
Привет. Прокоментируйте плиз. Я считаю, что с одной стороны при написании сервера нельзя выделять на каждое подключение по 1-2 потока, потому что это лишние ресурсы. С другой стороны нельзя писать всё в 1 потоке, потому что много многопроцессоров - не редкость.
Вывод: надо делать пул потоков, размером x*cpucount, у каждого потока есть свой массив сокетов, который передается в функцию select(). При этом слушающий сокет находится во всех массивах, а остальные сокеты каждый в своем, чтобы не пришлось синхронизировать.

Автор: Artemon 1.11.2010, 18:08
Завист на сколько клиентов расчитан сервер.

Если к примеру планируется клиентов 200-300, то можно без опасения делать один поток на одного клиента

Автор: boostcoder 1.11.2010, 18:15
leniviy, я всегда использую пул потоков. где кол-во потоков равно кол-ву ядер. проблем не замечал.

Цитата(Artemon @  1.11.2010,  18:08 Найти цитируемый пост)
Если к примеру планируется клиентов 200-300, то можно без опасения делать один поток на одного клиента 

к чему такой изврат?

Автор: Artemon 1.11.2010, 20:42
Это не изврат, а самый простой способ работать с несколькими клиентами.

Во многих случаях он оправдан, а конкретно - когда не ожидается большого числа подключений.

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

Автор: boostcoder 1.11.2010, 20:49
Цитата(Artemon @  1.11.2010,  20:42 Найти цитируемый пост)
Это не изврат, а самый простой способ работать с несколькими клиентами.

потому и изврат.

Цитата(Artemon @  1.11.2010,  20:42 Найти цитируемый пост)
Во многих случаях он оправдан, а конкретно - когда не ожидается большого числа подключений.

он оправдан только тогда, когда хочется что-то по быстрому на###кодить smile 
с точки зрения архитектуры такого сервера - она изначально в тупике.

Цитата(Artemon @  1.11.2010,  20:42 Найти цитируемый пост)
К томуже можно использовать пул потоков, не по количеству ядер, а по количеству предпологаемых клиентов.

но это уже верх изврата из всех извратов smile 

Автор: Artemon 1.11.2010, 20:56
Если можно написать сервер выполняющий свои задачи за 1 день, зачем на него тратить 3 дня, кто оплатит 2 дня разницы ?

Если есть время экперементировать и добиться техже результатов, но более изящно - ваше право.



Автор: boostcoder 1.11.2010, 20:59
Цитата(Artemon @  1.11.2010,  20:56 Найти цитируемый пост)
Если можно написать сервер выполняющий свои задачи за 1 день, зачем на него тратить 3 дня, кто оплатит 2 дня разницы ?

меня бы совесть загрызла за то, что написал такое Гэ..

Добавлено через 4 минуты и 58 секунд
тема уже закрыта, оказывается smile 

Автор: Artemon 2.11.2010, 08:40
Я очень часто слышу критику многопоточных серверов, но на практике у меня с 2007 года работает многопоточный сервер, с числом клиентов около тысячи, проблем никаких нет.

И самое узкое место в нем - это работа с БД, которая тратит намного больше ресурсов чем переключение/создание потоков.

Автор: leniviy 2.11.2010, 11:56
тысяча - это очень мало

Автор: Олег2005 2.11.2010, 20:40
Цитата(Artemon @  2.11.2010,  07:40 Найти цитируемый пост)
 но на практике у меня с 2007 года работает многопоточный сервер, с числом клиентов около тысячи, проблем никаких нет.

Одновременно?
Количество виртуальной памяти, резервируемой для начального стека потока по умолчанию равно 0x100000 - 1048576 б + память для кучи + еще что.....
Т.е. 100 клиентов - это примерно 100 Мб оперативки - только на системное обслуживание потоков
1000 клиентов - уже гигабайт......
А еще 1000 буферов приема/передачи в модуле TCP?
Так что один клиент один поток и одновременно 1000 клиентов - накладно.....
Потому эту модель и ругают.....


Автор: boostcoder 2.11.2010, 21:39
Цитата(Олег2005 @  2.11.2010,  20:40 Найти цитируемый пост)
1000 клиентов - уже терабайт......

гигабайт

Автор: leniviy 2.11.2010, 22:17
Кстати у меня есть маленький однопоточный шлюз Bluetooth->TCP . Когда я его кодил, оказалось, что всё не так просто.
На каждое соединение пришлось выделять структурку ака job с полем state, счетчиками и 2 FIFO буферами.
Пришлось добавлять switch(state)/case , чтобы резюмить прерванную передачу.
Все эти структурки лежат в мапе, и когда select() возвращает готовые к работе сокеты, они ищутся в этой мапе

Автор: Олег2005 2.11.2010, 23:15
Цитата(boostcoder @  2.11.2010,  20:39 Найти цитируемый пост)
гигабайт 

Пардон.
Ошибся smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)