![]() |
|
Модераторы: feodorv |
![]()
|
|
| MuForum |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 427 Регистрация: 13.6.2007 Где: Молдова, Кишинев Репутация: нет Всего: 4 |
Доброе время суток.
Работаю на "Borland C++ Builder 2009". Мне необходимо написать программу на подобие прокси-сервера для Online игры. (MMORPG) Необходимо создавать для одного пользователя два потока: 1. Клиент <> моя программа 2. моя программа <> Сервер Программа должна поддерживать ~1000 пользователей. То есть, это 2000 потоков + 1 прослушивающий(Listen) = Итого ~2001 потоков. Работаю я с асинхронными функциями передачи данных: WSA*() После многодневного чтения форумов я понял, что для моей задачи мне необходимо организовать пул потоков/Pool threads. - Так же я понял, что кол-во поток в пуле должен быть: кол-во процессоров + 1, а не так как писал Рихтер, что кол-во процессоров * 2. Собственно система передачи данных между клиентами у меня уже реализована и работает на ура. - Почему я создал данную тему? - Потому, что раньше кол-во игроков не достигало больше 120 пользователей, а как только это число резко выросло, я столкнулся с тем, что по достижению какого-то кол-во пользователей, новый пользователи подключится не могут, а старые продолжают играть. Во время подключения в таком случае пользователей получает ошибку номер 10053 (WSAGetLastError()). Во время чтения статей про многопоточность я познакомился с понятиями "переключение между потоками" и его негативном влияние на скорость обработки данных. Прочитал статью на RSDN: Эффективная многопоточность; Прочитал статью "Джеффри РИХТЕР "Windows для профессионалов"": Глава 11. Пулы потоков; - Многое прояснилось. Какую-то часть даже понял =) В общем меня заинтересовала реализации через: "Встроенная поддержка пула потоков". ( QueueUserWorkItem() ) - Только вот как применить эту функцию на практике не могу понять. Искал в гугле примеры, но кроме частных особо нечего и не встретишь. P.S. -> Прошу помощи в реализации. То есть, может кто-то подкинет название какой-то книги, либо примерчик(нормальный). Это сообщение отредактировал(а) MuForum - 9.8.2009, 18:58 -------------------- "Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли) |
|||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: нет Всего: 146 |
используя это я бы восплользовался Indy там есть уже прокси .... -------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| MuForum |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 427 Регистрация: 13.6.2007 Где: Молдова, Кишинев Репутация: нет Всего: 4 |
Мне необходимо немного другое ежели прокси-сервер, но по своей сути тоже самое. Мне необходимо написать спец.программу, которая будет пропускать через себя все игровые пакеты пользователей и проверять нужные аспекты, чтобы игроки не прибегали к некоторым "чудесам" игры. У меня встала задача реализовать пул потоков. Столкнулся я с этим в первые, поэтому пока как реализовать понимаю только в общих чертах. Перед созданием тему я несколько дней читал статьи по данной теме, чтобы иметь представление о том, чего мне нужно добиться. То есть, мне нужно создать пул потоков, чтобы потоки от пользователей вставали в очередь для обработки. # Добавлено: Когда подключается новый пользователь, я инициализирую класс "CS_Item", и помещаю его в список.
Далее я инициализирую класс "TS_CS" для обмена данными с клиентом.
После того, как пользователь заходит в игру и выбирает сервер на котором он хочет играть, я инициализирую класс "TS_SG" для обмена данными с сервером.
Далее уже происходит обмен данными между клиентом и сервером через мою программу, через эти два потока. P.S. -> Надеюсь изъяснился доступно. Это сообщение отредактировал(а) MuForum - 9.8.2009, 18:51 -------------------- "Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли) |
||||||||
|
|||||||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: нет Всего: 146 |
точнее ... и где вопросы ? -------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 1 Всего: 50 |
Там еще есть такое IdSchedulerOfThreadDefault (Indy 10). Сразу скажу, что не юзал этот компонент. Это сообщение отредактировал(а) Alca - 9.8.2009, 21:35 |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 5 Всего: 154 |
||||
|
||||
| SVN74 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 740 Регистрация: 5.5.2008 Где: Комсомольск на Дн епре Репутация: 1 Всего: 18 |
Я с такой штучкой сталкивался, - правда у меня было на блокирующих сокетах и применял я CreateThread, - тоже при большом количестве народу отсекало некоторых...
Дело было: accept - > CreateThread, - когда accept передавал в поток (КОПИЮ) сокета, то проходит определенное время создания нового потока, а accept продолжает работать получая новый сокет... Получается - пока создастся новый поток, то копия сокета до него не доходит. Я просто поставил задержку между созданием нового потока и созданием очередного сокета и все.... |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 5 Всего: 154 |
SVN74, порождать поток для каждого нового клиента - некошерно
|
|||
|
||||
| SVN74 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 740 Регистрация: 5.5.2008 Где: Комсомольск на Дн епре Репутация: 1 Всего: 18 |
||||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 5 Всего: 154 |
это не важно, механизм IOCP, позволяет организовать диспетчеризацию разных событий если вкратце, то выглядит оно так: ты создаешь порт завершения, связываешь объекты(файлы, сокеты) с ним, с каждым объектом(клиентом) может быть связан еще один объект(completion key), когда ты начинаешь операцию на сокете, она выполняется асинхронно(send/recv возвращают управление сразу, не дожидаясь, когда произойдет ввод/вывод) и с ней можно связать структуру OVERLAPPED(конечно это может быть не эта структура, а к примеру ее наследник, содержащий дополнительные поля). Дальше, когда операция завершается, ты можешь вызвать ф-ю GetQueuedCompletionStatus, и получить ключ завершения(completion key) и структуру OVERLAPPED(или то, что ты передал вместо нее), завершенной асинхронной операции. Эти данные однозначно идентифицируют клиента твоего сервера а так-же конкретную операцию ввода-вывода, которая завершилась для данного клиента. Типичный пример использования - ты создаешь М потоков, и в каждом из низ выполняется цикл, в котором вызывается ф-я GetQueuedCompletionStatus, это похоже на обработку сообщений windows, только в несколько потоков. Порт завершения можно настроить так, что-бы на нем могли выполняться одновременно только К потоков(К < M). К примеру, у тебя в пулле потоков - 20 потоков, а на порте завершения может работать только 10 потоков одновременно. Допустим в начальный момент времени, все потоки в режиме ожидания (сидят в ф-ии GetQueuedCompletionStatus). После того, как на порте завершения произойдет какое-либо событие, у тебя в одном из потоков, ф-я GetQueuedCompletionStatus, вернет управление, после чего твой код обработает это событие и снова вызовет эту ф-ю и будет ждать следующего события. Если произойдет 10 событий, то у тебя будут работать все 10 потоков. Если в этот момент произойдет 11-е событие, оно будет помещено в очередь, до тех пор, пока один из 10 работающих потоков не перейдет в состояние ожидания, к примеру вызвав ф-ю GetqueuedcompletionStatus. Но в состояние ожидания поток может перейти, вызвав к примеру ф-ю WrteFile(синхронно), либо WaitForSingleObject. В общем, если один из 10 работающих потоков по какой-либо причине должен будет что-нибудь ждать, то система разбудит еще один поток из пулла, и передаст туда 11-е событие. В результате, даже если у тебя в коде обработчиков событий есть синхронный ввод/вывод, или ожидание всяких локов, процессор простаивать не будет. В общем, механизм очень эффективен, для реализации высоко-нагруженного сервера лучше использовать именно его. Статья Русиновича - Inside IOCP Это сообщение отредактировал(а) Lazin - 10.8.2009, 08:11 |
|||
|
||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 1 Всего: 50 |
Модель порта завершения
http://r3code.livejournal.com/98391.html http://forum.sources.ru/index.php?showtopi...mp;view=showall Это сообщение отредактировал(а) Alca - 10.8.2009, 12:31 |
|||
|
||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 1 Всего: 50 |
||||
|
||||
| MuForum |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 427 Регистрация: 13.6.2007 Где: Молдова, Кишинев Репутация: нет Всего: 4 |
Модератор: Сообщение скрыто. -------------------- "Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли) |
|||
|
||||
| MuForum |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 427 Регистрация: 13.6.2007 Где: Молдова, Кишинев Репутация: нет Всего: 4 |
# for all - Нашел небольшую статью про "Порты завершения": Модель порта завершения;
- Может кому-то пригодится. -------------------- "Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли) |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Сети | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |