13.1.4. Сравнение poll() и select()

13.1.4. Сравнение poll() и select()

Обладая одинаковой функциональностью, poll() и select() также имеют существенные отличия. Наиболее очевидным отличием является тайм-аут, поддерживающий миллисекундную точность для poll() и микросекундную точность для select(). В действительности же это отличие почти незначительно, поскольку ни один системный вызов не будет подготовлен с точностью до микросекунды.

Более важное отличие связано с производительностью. Интерфейс poll() обладает несколькими свойствами, делающими его намного эффективнее, чем select().

1. При использовании select() ядру необходимо проверить все файловые дескрипторы между 0 и numfds - 1, чтобы убедиться, заинтересовано ли приложение в событиях ввода-вывода для этого файлового дескриптора. Для приложений с большим количеством открытых файлов это может привести к существенным затратам, поскольку ядро проверяет, какие именно файловые дескрипторы являются объектом интереса.

2. Набор файловых дескрипторов передается ядру как битовая карта для select() и как список для poll(). Сложные битовые операции, необходимые для проверки и установки структур данных fd_set, менее эффективны, чем простые проверки, требуемые для struct pollfd.

3. Поскольку ядро переписывает структуры данных, передаваемые select(), приложение вынуждено сбрасывать эти структуры каждый раз перед вызовом select(). С poll() результаты ядра ограничены элементом revents, что устраняет потребность в восстановлении структур данных после каждого вызова.

4. Использование структуры, основанной на множествах (например, fd_set) не масштабируется по мере увеличения количества доступных процессу файловых дескрипторов. Поскольку ее размер статичен, а не динамичен (обратите внимание на отсутствие соответствующего макроса, например, FD_FREE), она не может расширяться или сжиматься в соответствии с потребностями приложения (или возможностями ядра). В Linux максимальный файловый дескриптор, который можно установить в fd_set, равен 1023. Если понадобится больший файловый дескриптор, select() работать не будет.

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

Следующая короткая программа, подсчитывающая количество системных вызовов в секунду, демонстрирует, насколько poll() эффективнее select().

 1: /* select-vs-poll.с */

 2:

 3: #include <fcntl.h>

 4: #include <stdio.h>

 5: #include <sys/poll.h>

 6: #include <sys/select.h>

 7: #include <sys/signal.h>

 8: #include <unistd.h>

 9:

10: int gotAlarm;

11:

12: void catch(int sig) {

13:  gotAlarm = 1;

14: }

15:

16: #define HIGH_FD 1000

17:

18: int main(int argc, const char ** argv) {

19:  int devZero;

20:  int count;

21:  fd_set select Fds;

22:  struct pollfd pollFds;

23:

24:  devZero = open("/dev/zero", O_RDONLY);

25:  dup2(devZero, HIGH_FD);

26:

27:  /* с помощью signal выяснить, когда время истекло */

28:  signal(SIGALRM, catch);

29:

30:  gotAlarm =0;

31:  count = 0;

32:  alarm(1);

33:  while (!gotAlarm) {

34:   FD_ZERO(&selectFds);

35:   FD_SET(HIGH_FD, &selectFds);

36:

37:   select(HIGH_FD + 1, &selectFds, NULL, NULL, NULL);

38:   count++;

39:  }

40:

41:  printf("Вызовов select() в секунду: %d ", count);

42:

43:  pollFds.fd = HIGH_FD;

44:  pollFds.events = POLLIN;

45:  count = 0;

46:  gotAlarm = 0;

47:  alarm(1);

48:  while (!gotAlarm) {

49:   poll(&pollFds, 0, 0);

50:   count++;

51:  }

52:

53:  printf("Вызовов poll() в секунду: %d ", count);

54:

55:  return 0;

56: }

Здесь используется устройство /dev/zero, предоставляющее бесконечное количество нулей, что обеспечивает немедленный возврат системных вызовов. Значение HIGH_FD можно изменить, чтобы посмотреть, как деградирует select() по мере роста значений файловых дескрипторов.

В определенной системе при не очень высоком значении HIGH_FD, равном 2, программа показала, что ядро за секунду может обрабатывать в четыре раза больше вызовов poll(), чем вызовов select(). При увеличении HIGH_FD до 1000 эффективность poll() становится в 40 раз выше, чем у select().

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

5.8.4 Оператор select

Из книги Linux для пользователя автора Костромин Виктор Алексеевич

5.8.4 Оператор select Оператор select позволяет организовать интерактивное взаимодействие с пользователем. Он имеет следующий формат: select name [in word;] do list; doneВначале из шаблона word формируется список слов, соответствующих шаблону. Этот набор слов выводится в стандартный поток


6.9. Использование select и poll с очередями сообщений

Из книги UNIX: взаимодействие процессов автора Стивенс Уильям Ричард

6.9. Использование select и poll с очередями сообщений Одним из недостатков очередей сообщений System V является то, что они идентифицируются не дескрипторами, а идентификаторами. Поэтому с ними нельзя использовать функции select и poll (глава 6 [24]). ПРИМЕЧАНИЕ На самом деле одна из


13.1.6 Сравнение poll() и epoll

Из книги Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ автора Борри Хелен

13.1.6 Сравнение poll() и epoll Методы poll() и epoll существенно отличаются; poll() хорошо стандартизован, но плохо масштабируется, в то время как epoll существует только в Linux, но очень хорошо масштабируется. Приложения, наблюдающие за небольшим количеством файловых дескрипторов и


Оператор SELECT

Из книги Недокументированные и малоизвестные возможности Windows XP автора Клименко Роман Александрович

Оператор SELECT Оператор SELECT является для клиентов фундаментальным методом поиска наборов данных в базе данных. Он имеет следующую основную форму:SELECT[FIRST (m)] [SKIP (n)] [[ALL] | DISTINCT]<список-столбцов> [, [имя-столбца] | выражение | константа ]AS имя-алиаса]FROM


Конструкция SELECT ... INTO

Из книги Понимание SQL автора Грубер Мартин

Конструкция SELECT ... INTO Конструкция SELECT ... INTO обычна для PSQL. Когда из таблицы запрашиваются значения, предложение INTO позволяет сохранить их в переменных - в локальных переменных или в выходных аргументах. В этой процедуре нет выходных параметров. Мы используем переменную ANY


Конструкция FOR SELECT ... DO

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард

Конструкция FOR SELECT ... DO Для поиска множества строк в процедуре мы используем конструкцию FOR SELECT ... DO. Ее синтаксис:FOR<выражение-выбора>INTO <:переменная [, :переменная [, ...]] DO<составной-оператор>;<выражение-выбора> может быть любым запросом выбора, использующим


Раздел Select

Из книги автора

Раздел Select Но как же система узнает, какой из разделов ControlSetNNN необходимо использовать при обычной загрузке, какой нужно применять при загрузке последней удачной конфигурации, а какой вообще является испорченным? Именно для этих целей и предназначен раздел Select. Он


Оператор SELECT

Из книги автора

Оператор SELECT Оператор SELECT осуществляет выборку из базы данных и имеет наиболее сложную структуру среди всех операторов языка SQL. Практически любой пользователь баз данных в состоянии написать простейший оператор SELECT типаSELECT * FROM PC;который осуществляет выборку всех


Команда SELECT

Из книги автора

Команда SELECT SELECT * | { [ DISTINCT | ALL] <value expression>.,..} FROM { <table name> [ <alias> ] }.,.. [ WHERE <predicate>] [ GROUP BY { <column name> | <integer> }.,..] [ HAVING <predicate>] [ ORDERBY { <column name> | <integer> }.,..] [ { UNION [ALL]SELECT * | { [DISTINCT | ALL] < value expression >.,..} FROM { <table name> [<alias>]} .,.. [ WHERE <predicate> [ GROUP BY {


Глава 6 Мультиплексирование ввода-вывода: функции select и poll

Из книги автора

Глава 6 Мультиплексирование ввода-вывода: функции select и poll 6.1. Введение В разделе 5.12 мы видели, что наш TCP-клиент обрабатывает два входных потока одновременно: стандартный поток ввода и сокет TCP. Проблема, с которой мы столкнулись, состояла в том, что пока клиент был


6.10. Функция poll

Из книги автора

6.10. Функция poll Функция poll появилась впервые в SVR3, и изначально ее применение ограничивалось потоковыми устройствами (STREAMS devices) (см. главу 31). В SVR4 это ограничение было снято, что позволило функции poll работать с любыми дескрипторами. Функция poll предоставляет


Интерфейс /dev/poll

Из книги автора

Интерфейс /dev/poll В Solaris имеется специальный файл /dev/poll, с помощью которого можно опрашивать большее количество дескрипторов файлов. Проблема select и poll состоит в том, что список дескрипторов приходится передавать при каждом вызове. Устройство опроса поддерживает информацию