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

Терминалы не получают сигналы о возможности вывода и разрыве соединения.

С версии ядра 2.4.19 Linux передает сигнал о возможности вывода вторичному псевдотерминалу. Он генерируется всякий раз, когда ввод принимается на первичной стороне.

Именованные каналы и очереди FIFO

Для считывающего конца именованного канала или очереди FIFO сигнал генерируется в следующих ситуациях:

• данные записаны в канал (даже если там уже находится непрочитанный ввод);

• записывающий конец канала закрыт.

Для записывающего конца именованного канала или очереди FIFO сигнал генерируется в следующих ситуациях:

• чтение из канала увеличивает объем свободного пространства в нем, благодаря чему становится возможным записать без блокировки PIPE_BUF байтов;

• считывающий конец канала закрыт.

Сокеты

Ввод/вывод на основе сигналов поддерживает датаграммные сокеты в UNIX- и интернет-доменах. Сигнал генерируется в следующих ситуациях:

• в сокет поступает входящая датаграмма (даже если в очереди находятся другие непрочитанные датаграммы);

• в сокете происходит асинхронная ошибка.

Ввод/вывод на основе сигналов работает также и для потоковых сокетов в обоих доменах. Сигнал генерируется в следующих ситуациях:

• слушающий сокет принял новое соединение;

• завершается TCP-запрос connect(); то есть активный конец TCP-соединения входит в состояние ESTABLISHED (см. рис. 57.5). Условие не срабатывает для сокетов в домене UNIX;

• сокет принял новый ввод (даже если в нем уже доступны непрочитанные данные);

• удаленная сторона закрывает свою записывающую часть соединения с помощью вызова shutdown() или все соединение целиком, используя вызов close();

• становится возможным вывод из сокета (например, когда освобождается место в его исходящем буфере);

• в сокете происходит асинхронная ошибка.

Файловые дескрипторы inotify

Сигнал генерируется, когда становится доступным файловый дескриптор inotify, то есть если с любым из файлов, которые он отслеживает, происходит какое-то событие.

59.3.3. Эффективное использование ввода/вывода на основе сигналов

В приложениях, которым нужно наблюдать за большим количеством (то есть тысячами) файловых дескрипторов (например, отдельными видами сетевых серверов), ввод/вывод на основе сигналов может обеспечить значительное увеличение производительности по сравнению с вызовами select() и poll(). Дело в том, что ядро «запоминает» список отслеживаемых дескрипторов и оповещает программу только в момент, когда с ними происходят события ввода/вывода. Таким образом, производительность программы, применяющей ввод/вывод на основе сигналов, масштабируется в зависимости от количества событий, а не подконтрольных файловых дескрипторов.

Чтобы применять весь потенциал этой методики, нужно выполнить два шага:

• воспользоваться вызовом fcntl() с флагом F_SETSIG (поддерживается только в Linux) с целью указать сигнал реального времени, который должен быть доставлен вместо SIGIO, когда станет возможным ввод/вывод для заданного файлового дескриптора;

• указать флаг при использовании вызова sigaction(), чтобы установить обработчик сигнала реального времени, указанного в предыдущем шаге (см. раздел 21.4).

Операция fcntl() F_SETSIG позволяет указать альтернативный сигнал, который должен быть доставлен вместо SIGIO как оповещение о возможности ввода/вывода для файлового дескриптора:

if (fcntl(fd, F_SETSIG, sig) == -1)

errExit("fcntl");

F_GETSIG выполняет действие, обратное операции F_SETSIG: извлекает сигнал, установленный на данный момент для файлового дескриптора:

sig = fcntl(fd, F_GETSIG);

if (sig == -1)

errExit("fcntl");

Для того чтобы получить определения констант F_SETSIG и F_GETSIG из заголовочного файла , следует определить макрос проверки возможностей _GNU_SOURCE.

Флаг F_SETSIG для изменения сигнала, оповещающего о возможности ввода/вывода, служит двум целям, каждая из которых является обязательной при мониторинге большого количества событий ввода/вывода для множества файловых дескрипторов.

• По умолчанию для оповещения о возможности ввода/вывода применяется стандартный сигнал SIGIO, который минует очередь. Если события начнут поступать в момент, когда этот сигнал заблокирован (возможно, его обработчик уже вызван), то все они, кроме первого, будут утеряны. При использовании вместо SIGIO сигнала реального времени F_SETSIG уведомления будут складываться в очередь.

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

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