Читаем Linux API. Исчерпывающее руководство полностью

Макросы вида FD_* оперируют структурами данных в пользовательском пространстве, а реализация вызова select() в ядре способна обслуживать наборы дескрипторов больших размеров. Тем не менее библиотека glibc не предусматривает простого способа изменения константы FD_SETSIZE. При необходимости изменить это ограничение придется отредактировать определение в соответствующих заголовочных файлах. glibc. Но если нужно отслеживать большое количество дескрипторов, то интерфейс epoll, вероятно, будет более предпочтительным по сравнению с вызовом select(). Причины этого будут описаны позже в данной главе.

Аргументы readfds, writefds и exceptfds возвращают результат выполнения. Структуры fd_set, на которые они указывают, должны содержать нужные нам наборы дескрипторов до вызова select(); здесь применяются макросы FD_ZERO() и FD_SET(). Вызов select() изменяет все эти структуры таким образом, что на момент возвращения они содержат наборы с готовыми дескрипторами. (Поскольку структуры изменяются во время вызова, их нужно заново инициализировать, если они используются многократно внутри цикла.) Содержимое структур можно изучить с помощью макроса FD_ISSET().

Если не интересует какой-то определенный вид событий, то соответствующему аргументу fd_set можно присвоить NULL. Подробности о каждом из трех видов событий будут описаны в подразделе 59.2.3.

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


Аргумент timeout

Аргумент timeout влияет на поведение вызова select(), связанное с блокировкой. Ему можно присвоить либо NULL (в этом случае select() перманентно блокируется), либо указатель на структуру timeval:

struct timeval {

time_t tv_sec; /* Секунды */

suseconds_t tv_usec; /* Миллисекунды (long int) */

};

Если оба поля аргумент timeout равны 0, то вызов select() не блокируется; он просто проверяет заданные файловые дескрипторы на готовность и сразу же возвращается. В противном случае timeout определяет максимальное время ожидания вызова select().

Структура timeval позволяет указывать время с точностью до микросекунд, однако точность самого вызова ограничена системными часами (см. раздел 10.6). Согласно стандарту SUSv3 время ожидания округляется в большую сторону, если оно не делится без остатка.

Стандарт SUSv3 требует, чтобы максимально допустимое время ожидания не превышало 31 дня. Большинство реализаций UNIX допускают куда большие значения. На платформе Linux/x86-32 тип time_t представляет собой 32-разрядное целое число, поэтому максимальное значение измеряется многими годами.

Если аргумент timeout равен NULL или указывает на структуру, содержащую ненулевые поля, то вызов select() блокируется, пока не возникнет одно из следующих событий:

• хотя бы один из файловых дескрипторов, указанных в наборах readfds, writefds или exceptfds, становится готовым;

• вызов прерывается обработчиком сигнала;

• истекает время, указанное в аргументе timeout.

В старых версиях UNIX вызов sleep() поддерживал значения лишь с точностью до секунды (в отличие от, скажем, nanosleep()). Для эмуляции этой возможности аргументу nfds вызова select() передавался 0, аргументам readfds, writefds и exceptfds присваивался NULL, а в timeout указывался желаемый интервал.

Если в Linux вызов select() возвращается, сигнализируя о готовности одного или нескольких файловых дескрипторов, и при этом время ожидания не равно NULL, то структура, на которую указывает аргумент timeout, в итоге обновляется и сообщает о том, сколько времени оставалось до истечения заданного интервала. Но стоит отметить, что данное поведение зависит от реализации. Стандарт SUSv3 позволяет оставлять структуру, на которую указывает timeout, без изменений — именно так и поступает большинство UNIX-систем. Портируемые приложения, использующие вызов select() внутри цикла, должны всегда передавать уже инициализированную структуру со временем ожидания и игнорировать информацию, возвращаемую в ней в результате этого вызова.

Стандарт SUSv3 гласит, что структура, на которую указывает аргумент timeout, может быть обновлена только в случае успешного завершения вызова select(). Однако в Linux обновление происходит, даже если вызов прерывается обработчиком сигнала (и, как следствие, завершается ошибкой EINTR). Это делается для того, чтобы сообщить о том, сколько осталось до истечения времени ожидания (если бы вызов завершился успешно).

Если предварительно воспользоваться системным вызовом personality() (доступным только в Linux), чтобы установить двоичный программный интерфейс (ABI), содержащий бит STICKY_TIMEOUTS, то вызов select() не станет изменять структуру, на которую указывает timeout.


Значение, возвращаемое вызовом select()

Перейти на страницу:

Похожие книги

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных
1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
C# 4.0: полное руководство
C# 4.0: полное руководство

В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки. Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию

Герберт Шилдт

Программирование, программы, базы данных