Должны ли мы использовать poll () или select ()? - PullRequest
15 голосов
/ 09 декабря 2011

Я полностью осознаю основные различия между poll() и select():

  • select() поддерживает только фиксированное количество файловых дескрипторов
  • select()предположительно поддерживается на большем количестве систем
  • poll() позволяет немного более детально управлять типами событий
  • poll() реализации могут отличаться в некоторых деталях

Однакоони оба выполняют одну и ту же задачу примерно одинаково.Итак:

Должны ли мы использовать poll() или select()?


РЕДАКТИРОВАТЬ: Могу добавить, что меня не интересует epoll(), так какпереносимость беспокоит меня.Кроме того, libev(ent) также не вариант, так как я задаю этот вопрос, потому что я пишу свою собственную библиотеку замены для libev(ent).

Ответы [ 6 ]

17 голосов
/ 09 декабря 2011

Все дистанционно современные системы имеют poll, и этот интерфейс значительно превосходит select / pselect практически во всех отношениях:

  • poll позволяет более детально определять состояние, чем select.
  • poll не имеет ограничений на максимальный дескриптор файла, который вы можете использовать (и, что более важно, не имеет критических уязвимостей, когда вы не можете проверить дескрипторы файлов после ограничения FD_SETSIZE).

Единственные недостатки, которые я могу придумать при использовании poll, это то, что:

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

Конечно, переносимость poll больше не рассматривается. Любая система, достаточно старая для отсутствия poll, полна стольких уязвимостей, что ее не следует подключать к сети.

Таким образом, если у вас нет особых потребностей (небольшие интервалы времени ожидания, неприятные взаимодействия сигналов, масштабирование до миллионов постоянных соединений и т. Д.), Я просто использовал бы poll и покончил бы с этим. Как уже упоминалось, libevent также является опцией, но это не чистый / безопасный код (его использование select фактически вызывает опасный UB, пытающийся обойти ограничения select!), И я нахожу код, который использует libevent обычно намного сложнее, чем код, который просто использует poll напрямую.

4 голосов
/ 09 декабря 2011

На самом деле я бы порекомендовал boost :: asio, тогда вы можете попробовать обе реализации и протестировать, чтобы увидеть, что лучше всего подходит для вашей установки.

4 голосов
/ 09 декабря 2011

Если вы пишете для GNU / Linux, посмотрите на epoll (7).

Но для большей части межплатформенной поддержки вы могли бы изучить использование libevent. http://libevent.org/

На самом деле, трудно рекомендовать одну реализацию опроса / выбора, не зная специфики того, что вы пытаетесь сделать.

2 голосов
/ 09 декабря 2011

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

0 голосов
/ 09 декабря 2011

Опрос Apple () имеет проблемы с TTY, IME.Там, где важна переносимость, select () может быть лучшим выбором.

0 голосов
/ 09 декабря 2011

В зависимости от ваших потребностей, я бы порекомендовал либо poll, либо ::boost::asio. Я считаю, что libevent довольно громоздок, и в нем есть все, что ориентировано на C и / или на обработку протоколов более высокого уровня.

Я бы не рекомендовал select. Я видел, как реализации select невидимо терпят неудачу странным и странным образом, потому что предел дескриптора был превышен. И лучшее, что вы можете сделать, - это заставить его потерпеть неудачу очевидным образом. Может быть, это очень маловероятно для вашего приложения, но я бы не рискнул.

А в наше время poll доступен почти везде select есть. О единственном месте это не Windows. Но, ИМХО, если вы хотите кросс-платформенной переносимости на эту платформу, вам лучше использовать красивую оболочку, такую ​​как ::boost::asio, которая прекрасно оборачивает наиболее эффективную технику ОС.

...