2013-07-04 2 views
-1

Я работаю над проектом MMO game server, и у меня есть проблема. Это ограничение метода select(). Я хочу обрабатывать более 1024 сокетов ввода-вывода с одним потоком. Я хочу сделать это с помощью одного потока, потому что я попытался создать многопоточную систему обработки. Эта система создает 3 потока (например, в 4-ядерном процессоре, 1 является основным, 3 - обработчиком select()), который обрабатывает метод select(), но снова возникает другая проблема, теперь наш предел ушел в 3072 (1024 * 3) и это не решение! После этой идеи я хочу создать неблокирующую систему сокетов, с этой системой я назвал 2 разных метода select в одном отдельном потоке, как это; "select() select()". Они возвращаются в порядок, и я могу обращаться с ними в порядке. Но есть другая проблема, я думаю. Если я хочу реализовать поток, подобный методам while (true) {select() select()} "и select() (неблокирующим), я перегружаю CPU как пустой блок while (true). Если я хочу сделать тайм-аут select(), я не могу обработать нижний select() в реальном времени. Теперь я не могу сделать для этого алгоритм. Может ли кто-нибудь помочь мне в этом?Обработка более 1024 сокетов?

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

НАЧАЛЬНОЕ РЕШЕНИЕ (я думаю): Мне не нужно обрабатывать наносекунды для операции ввода-вывода, потому что нет смысла обрабатывать его. Опрос - это хороший способ обработки более чем 1024 сокетов. Я буду изучать что-то для понимания систем MMO. И последнее, что я сделаю некоторые тесты, и я попробую что-нибудь, прежде чем задать вопрос :) Спасибо!

EDIT: Я новый в этом Q & Платформа. Можете ли вы сказать мне, что не так с моим вопросом, после того, как я дал отрицательный отзыв? :)

+2

«Я хочу, чтобы мой собственный!» FYI, epoll требует поддержки ядра. Вам нужно будет написать модуль ядра. IOW, просто используйте epoll. –

+1

Кроме того, это, вероятно, вопрос XY. «из-за чего-то» рассказывают нам, что это такое, и, возможно, мы можем помочь решить эту проблему вместо этого, поскольку epoll - это действительно способ пойти. –

+0

@rightfold no, я хочу использовать метод select(). Я добавил причины, по которым я не хочу использовать ~ опрос. – PiLaWYeR

ответ

7

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

Даже poll не делает намного лучше, чем select при масштабировании в тысячи подключений.У него нет select (минимальное) ограничение на количество файловых дескрипторов, которые вы можете опросить, но он по-прежнему масштабируется линейно с количеством подключений.

Что вы действительно должны использовать, являются такие специфичные для платформы объекты, как epoll и kqueue. Они значительно отличаются (обычно O (1),), но, очевидно, они не переносимы.

Я всерьез предлагаю вам рассмотреть что-то вроде libev, который представляет собой переносную, испытанную и тонкую обертку вокруг специфичных для платформы средств и услуг.

Это потому, что методы конкретных платформ (например, порты завершения select, poll, epoll, kqueue, I/O, порты событий и т.д.), различные формы друг от друга, и ни один из них не доступна на более чем один или два платформ или их пределов, а детали их поведения немного отличаются. Эти средства могут даже измениться с одной версии ОС на следующую (например, на Linux 2.6.9, IIRC.)

Даже если вы не имеете дело с переносимостью или будущей проверкой кода, такая библиотека может обеспечить вы с большей функциональностью и приятным интерфейсом. больше

две библиотеки, вы можете попробовать это libevent (чуть больше и медленнее, но больше возможностей) и libuv (если вам нужна Windows, портативность.)

+0

Да, я попробую. (Как я уже говорил еще 2 раза) – PiLaWYeR

+1

@PiLaWYeR он просто добавляет его в качестве ответа, потому что комментарии на самом деле не место для решений. Поэтому, даже если вы, возможно, уже слышали об этом, это хорошая идея для этого, поэтому будущие пользователи могут знать, что это потенциальное решение. –

+0

Спасибо @ Jean-BernardPellerin. Именно это я и должен делать. Я знаю, что этот вопрос уже имеет принятый ответ, но кто-то, кто ищет тему этого вопроса, может приехать сюда, и я чувствую, что принятый в настоящее время ответ не предоставляет достаточной информации или каких-либо решений. Вот почему я добавляю свои 2 цента. – yzt

4

Учитывая требования, которые вы задали, ваша проблема не имеет решения.

  • нормальный способ преодолеть предел select() «s из FD_SETSIZZE (1024) дескрипторов файлов является использование poll() (или даже лучше альтернативы Epoll и Kqueue), но вы отвергли этот вариант.
  • В противном случае вы всегда могли бы преодолеть эту проблему, вызывая многократную параллельную связь между select() в разных потоках с различными наборами дескрипторов файлов ... но вы тоже отклонили эту опцию.

Я не верю, что действительно может быть любое другое решение!

Возможно, вам следует объяснить, почему не подходят как опции poll(), так и вариант нити. Ваши требования кажутся искусственными ограничениями без оправдания.

+3

И мораль заключается в том, что вы не можете решить проблемы, если избегаете решений. \ * Control + W \ * –

+0

метод опроса не является быстрым. select может обрабатывать операцию в микросекундах, но опрос не может. Это моя причина «почему я не хочу использовать опрос». – PiLaWYeR

+0

LOL darn you [rightfold] (http://stackoverflow.com/users/142019/rightfold) Я нажал эту комбинацию клавиш! ;) –

Смежные вопросы