Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Сети > select fd_set максимальный размер |
Автор: azesmcar 14.4.2009, 11:46 | ||
Добрый день, Чем больше работаю с сокетами - тем больше убеждаюсь что я чего-то не понимаю конкретно ![]() функция select принимает параметр - структуру fd_set.
что это? нельзя проверять на события больше 64 сокетов? Это как-то ненормально, в МСДН написано что можно изменить значение FD_SETSIZE перед иклудом - делаю вывод что это нормально - но..на одном форуме прочел что это неправильно, можно найти другое решение, правда не сказано какое..делаю вывод - можно циклом пихать сокеты в fd_set под 64 штуки на итерацию и делать select, но если у меня блокирующий select? Пока первые 64 не выдадут события - на остальных серверу будет наплевать..хмммм, кто что скажет? |
Автор: JackYF 14.4.2009, 14:22 |
Покурил маны, нигде число 64 не увидел. |
Автор: azesmcar 14.4.2009, 14:24 |
JackYF В манах я тоже не увидел..это студия - код кроссплатформенный |
Автор: MAKCim 14.4.2009, 21:15 |
вполне нормально хочешь больше - юзай poll |
Автор: azesmcar 14.4.2009, 22:33 | ||
так нету его под виндоуз. Мне нужно кроссплаторменно.. если я сделаю #define FD_SETSIZE 1000 перед инклудом это мне напомнят в судный день? Смертных грех или не очень? |
Автор: J0ker 15.4.2009, 01:20 |
курите тщательней http://support.microsoft.com/kb/111855 |
Автор: azesmcar 15.4.2009, 08:35 | ||
это кому предназначалось? тому кто маны курил? ![]() 1. маны к мсдн отношения не имеют 2. я сказал что в мсдн нашел, в манах - нет |
Автор: Олег2005 15.4.2009, 13:12 |
Как пишет Р. Стивенс, FD_SETSIZE для большинства юниксподобных систем равно 256. Простое увеличение через дефайн Стивенс пишет - может не действовать - без перекомпиляции ядра. Он же пишет - что для кросплатформенности не стоит изменять это значение. |
Автор: azesmcar 15.4.2009, 13:14 | ||||
Олег2005 Замечательно, добавил проблем на мою голову..а решение??? ![]() Добавлено через 2 минуты и 52 секунды Из МСДН
вот только я тоже прочел что
так что же делать? Изменять только под виндоуз? Не важно, 256 тоже маловато. ![]() |
Автор: Олег2005 15.4.2009, 13:32 |
Сами эти проблемы высыпали себе на голову....... А решение? Из двух(трех) зол - выбирать наименьшее. Увы, всем угодить не получается.... |
Автор: azesmcar 15.4.2009, 13:38 | ||||
т.е. чем я себе эти проблемы создал? тем что программистом стал или что кроссплатформенный код надо писать? ![]()
а которое наименьшее?? мне нужна поддержка обработки ну как минимум 500 сокетов. |
Автор: azesmcar 15.4.2009, 22:28 | ||||
Олег2005 В принципе у меня неблокирующий сокет. Я могу циклом засовывать сокеты в селект по 64 штуки за раз. Как вариант эта методика имеет права на жизнь? Добавлено через 2 минуты и 19 секунд
В никсах есть poll как сказал MAKCim, но...как сказали вы - увы ![]()
![]() |
Автор: Олег2005 15.4.2009, 22:48 | ||
Это понятно
А вот тут я не особенно врубаюсь ![]() Засовывать вы имеет право - FD_SET'ом 64 сокета. И что это даст? Поясните свое предположение - алгоритм в двух словах...... |
Автор: azesmcar 15.4.2009, 23:35 |
Олег2005 Засовываю 64 сокета. Вызываю селект. Есть события, обрабатываю, нет событий - засовываю еще 64, пока не кончатся. Таймаут на селект ставлю 0. |
Автор: vinick 16.4.2009, 11:27 | ||
Если таймаут 0, то селект будет ждать пока на сокетах не произойдет события. Так что если нет событий, то другие ты вставить не сможешь. Если ставить маленький, но реальный, таймаут, то тоже возможны ситуации когда сокет с данными простаивает слишком долго из-за того что он оказался в конце твоей очереди. Может все-таки лучше использовать другие механизмы, для которых нет ограничения на количество сокетов. А для кросс-платформености использовать готовые обертки типа boost.asio или ACE или самому написать такую обертку. |
Автор: MAKCim 16.4.2009, 11:35 |
в linux, ребята, есть epoll, а это реально мощная штука ![]() |
Автор: azesmcar 16.4.2009, 11:37 | ||||||
где такое написано? селект блокируется если передать 0 вместо timeout а не если передать структуру с таймаутом 0. МСДН
Так я и пишу обертку. а как ее писать то? MAKCim Вы видимо темой ошиблись ![]() http://forum.vingrad.ru/forum/topic-248292.html Я прекрасно знаю что линукс мощная штука...проблема в кроссплатформенности ![]() |
Автор: vinick 16.4.2009, 11:54 | ||||
Извиняюсь. я почему-то решил что передаешь именно нулевой указатель.
По другому наверно никак. |
Автор: azesmcar 16.4.2009, 12:00 | ||
Ну пока я ничего не передаю ![]() vinick про "I/O completion ports" если можно подробнее... кстати, а в БСД что, нет poll, epoll? |
Автор: vinick 16.4.2009, 12:16 |
я про них знаю только название и то что они являются аналогом epoll в линуксе ![]() poll скорее всего есть - это тот же select только в профиль. а вот epoll это чисто линуксовая штучка, ее аналогом в BSD является kqueue. Подробнее по *nix-вым механизмам можешь посмотреть здесь http://www.kegel.com/c10k.html |
Автор: Олег2005 16.4.2009, 12:42 | ||
В лоб - но работать будет ![]() Про IO completion port я уже где-то выкладывал - лень искать, выложу еще раз: |
Автор: azesmcar 16.4.2009, 13:21 | ||||
Работать то будет..но хотелось бы чтобы работало хорошо ![]()
спасибо, посмотрел..так тут разница с линуксом огромная, практически нужно разные классы писать под виндоуз и под линукс..надо подумать что предпочтительней.. |
Автор: azesmcar 16.4.2009, 13:51 | ||
Еще одна мысль. Поскольку сокеты все неблокирующие (так как в этом потоке мне нужно проверять и другие события, не только на сокетах), можно убрать селект вообще. Подробнее... На данный момент (если забыть про проблему селекта) у меня работает такая схема при каждой проверке события
в случае если убрать селект и проверять события функцией recv на каждом сокете по отдельности, одной итерацией по сокетам будет меньше..что вы об этом думаете? |
Автор: vinick 16.4.2009, 15:11 | ||
recv как ни крути - системный вызов. Пробежаться по массиву и проверить событие в fd_set в юзерспейсе при большом количестве дескрипторов, будет дешевле чем впустую дергать recv для каждого сокета. Тут лучше будет экономить не на итерациях по сокетам, а на системных вызовах. |
Автор: azesmcar 16.4.2009, 15:16 | ||
vinick
а точно что будет медленее? подумать не стоит? |
Автор: Олег2005 16.4.2009, 15:24 | ||
Согласен. |
Автор: azesmcar 16.4.2009, 15:44 |
![]() ![]() ![]() ладно...буду думать. всем спасибо, решенным пока не отмечаю, мало ли.. |
Автор: vinick 16.4.2009, 16:11 |
azesmcar, как я понял ты используешь С++, тогда я порекомендую использовать готовую библиотеку http://en.wikipedia.org/wiki/Asio_C%2B%2B_library Она проста в использовании, кроссплатформенна, подерживает не только windows и Linux но и Solaris, MacOSX и т.п., состоит только из *.h фалов, Она включена в состав буста, но может быть использована и отдельно. В крайнем случае ты можешь посмотреть на ее внутрености и попробовать реализовать свое по образу и подобию, выкинув лишнее, там правда очень много шаблонной магии. Короче то что надо ![]() |
Автор: azesmcar 16.4.2009, 16:26 |
vinick С++ конечно ![]() ![]() У меня своя кроссплатформенная библиотека, с обработкой событий (делегаты, итд, итп...) потому пишу свой класс, чтобы встраивался под общую архитектуру и выдавал события в нужном мне виде...у меня болезненный принцип не использовать ничего написанного сторонними производителями (после работы в одной компании остался осадок ![]() ![]() Завтра скачаю посмотрю - отпишусь..сегодня уже не успеть.. Спасибо |
Автор: MAKCim 16.4.2009, 16:30 |
ошибся темой? ![]() |
Автор: azesmcar 16.4.2009, 16:39 | ||
MAKCim![]()
Под линукс можно много чего красивого сделать..но нужно кроссплатформенно. |
Автор: J0ker 16.4.2009, 20:22 |
boost.Asio - pools, queues, IO completion ports |
Автор: Олег2005 16.4.2009, 21:44 |
Кстати, а есть какое руководство - с доходчивым описанием? |
Автор: J0ker 16.4.2009, 23:48 | ||
внимательно почитайте Overview - Core Concepts and Functionality и ознакомьтесь с паттерном "реактор" |