Коллизии при вызове функции select
Коллизии при вызове функции select
Рассматривая данный пример в 4.4BSD, мы можем исследовать еще одну проблему, которая встречается довольно редко и поэтому часто остается непонятой до конца. В разделе 16.13 [128] говорится о коллизиях (collisions), возникающих при вызове функции select несколькими процессами на одном и том же дескрипторе, и о том, каким образом ядро решает эту проблему. Суть проблемы в том, что в структуре socket предусмотрено место только для одного идентификатора процесса, который выводится из состояния ожидания по готовности дескриптора. Если же имеется несколько процессов, ожидающих, когда будет готов данный дескриптор, то ядро должно вывести из состояния ожидания все процессы, блокированные в вызове функции select, так как ядро не знает, какие именно процессы ожидают готовности данного дескриптора.
Коллизии при вызове функции select в нашем примере можно форсировать, предваряя вызов функции accept из листинга 30.9 вызовом функции select в ожидании готовности к чтению на прослушиваемом сокете. Дочерние процессы будут теперь блокированы в вызове функции select, а не в вызове функции accept. В листинге 30.11 показана изменяемая часть функции child_main, при этом измененные по отношению к листингу 30.9 строки отмечены знаками +.
Листинг 30.11. Модификация листинга 30.9: блокирование в вызове select вместо блокирования в вызове accept
printf("child %ld starting ", (long)getpid());
+ FD_ZERO(&rset);
for (;;) {
+ FD_SET(listenfd, &rset);
+ Select(listenfd+1, &rset, NULL, NULL, NULL);
+ if (FD_ISSET(listenfd, &rset) == 0)
+ err_quit("listenfd readable");
+
clilen = addrlen;
connfd = Accept(listenfd, cliaddr, &clilen);
web_child(connfd); /* обработка запроса */
Close(connfd);
}
Если, проделав это изменение, мы проверим значение счетчика ядра BSD/OS nselcoll, мы увидим, что в первом случае при запуске сервера произошло 1814 коллизий, а во втором случае — 2045. Так как при каждом запуске сервера два клиента создают в сумме 5000 соединений, приведенные выше значения указывают, что примерно в 35-40% случаев вызовы функции select приводят к коллизиям.
Если сравнить значения времени, затраченного центральным процессором в этом примере, то получится, что при добавлении вызова функции select это значение увеличивается с 1,8 до 2,9 с. Частично это объясняется, вероятно, добавлением системного вызова (так как теперь мы вызываем не только accept, но еще и select), а частично — накладными расходами, связанными с коллизиями.
Из этого примера следует вывод, что когда несколько процессов блокируются на одном и том же дескрипторе, лучше, чтобы эта блокировка была связана с функцией accept, а не с функцией select.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
13.1.4. Сравнение poll() и select()
13.1.4. Сравнение poll() и select() Обладая одинаковой функциональностью, poll() и select() также имеют существенные отличия. Наиболее очевидным отличием является тайм-аут, поддерживающий миллисекундную точность для poll() и микросекундную точность для select(). В действительности же это
Глава 6 Мультиплексирование ввода-вывода: функции select и poll
Глава 6 Мультиплексирование ввода-вывода: функции select и poll 6.1. Введение В разделе 5.12 мы видели, что наш TCP-клиент обрабатывает два входных потока одновременно: стандартный поток ввода и сокет TCP. Проблема, с которой мы столкнулись, состояла в том, что пока клиент был
Максимальное число дескрипторов для функции select
Максимальное число дескрипторов для функции select Ранее мы сказали, что большинство приложений не используют много дескрипторов. Например, редко можно найти приложение, использующее сотни дескрипторов. Но такие приложения существуют, и часто они используют функцию select
Тайм-аут для функции recvfrom (функция select)
Тайм-аут для функции recvfrom (функция select) Мы демонстрируем вторую технологию для установки тайм-аута (использование функции select) в листинге 14.3. Здесь показана наша функция readable_timeo, которая ждет, когда дескриптор станет готов для чтения, но не более заданного числа
Простой пример использования функции select
Простой пример использования функции select Теперь мы переделаем код нашего получателя внеполосных данных и вместо сигнала SIGURG будем использовать функцию select. В листинге 24.3 показана принимающая программа.Листинг 24.3. Принимающая программа, в которой (ошибочно)
5.8.4 Оператор select
5.8.4 Оператор select Оператор select позволяет организовать интерактивное взаимодействие с пользователем. Он имеет следующий формат: select name [in word;] do list; doneВначале из шаблона word формируется список слов, соответствующих шаблону. Этот набор слов выводится в стандартный поток
Раздел 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 {
Оператор SELECT
Оператор SELECT Оператор SELECT является для клиентов фундаментальным методом поиска наборов данных в базе данных. Он имеет следующую основную форму:SELECT[FIRST (m)] [SKIP (n)] [[ALL] | DISTINCT]<список-столбцов> [, [имя-столбца] | выражение | константа ]AS имя-алиаса]FROM
Конструкция SELECT ... INTO
Конструкция SELECT ... INTO Конструкция SELECT ... INTO обычна для PSQL. Когда из таблицы запрашиваются значения, предложение INTO позволяет сохранить их в переменных - в локальных переменных или в выходных аргументах. В этой процедуре нет выходных параметров. Мы используем переменную ANY
Конструкция FOR SELECT ... DO
Конструкция FOR SELECT ... DO Для поиска множества строк в процедуре мы используем конструкцию FOR SELECT ... DO. Ее синтаксис:FOR<выражение-выбора>INTO <:переменная [, :переменная [, ...]] DO<составной-оператор>;<выражение-выбора> может быть любым запросом выбора, использующим