Чтение онлайн

на главную

Жанры

UNIX: разработка сетевых приложений
Шрифт:
ПРИМЕЧАНИЕ

А что произойдет, если сигнал SIGIO не будет блокирован во время проверки переменной nqueue, используемой совместно основным циклом и обработчиком сигналов? Может случиться так, что проверка nqueue покажет нулевое значение, а сразу после проверки возникнет сигнал и nqueue станет равна 1. Далее мы вызовем функцию sigsuspend и перейдем в режим ожидания, в результате чего пропустим сигнал. После вызова функции sigsuspend мы не выйдем из режима ожидания, пока не поступит другой сигнал. Это похоже на ситуацию гонок, описанную в разделе 20.5

Разблокирование SIGIO и отправка ответа

46-51
Разблокируем сигнал SIGIO с помощью вызова
sigprocmask
, чтобы вернуть маске сигналов процесса значение, сохраненное ранее (
oldmask
). В этом случае ответ посылается с помощью функции
sendto
. Индекс
iget
увеличился на 1, и если его значение совпадает с количеством элементов массива, он снова обнуляется. Массив используется как кольцевой буфер. Обратите внимание, что нет необходимости блокировать сигнал
SIGIO
во время изменения переменной
iget
, поскольку этот индекс используется только в основном цикле и никогда не изменяется обработчиком сигнала.

Блокирование SIGIO

52-54
Сигнал
SIGIO
блокируется, а значение переменной
nqueue
уменьшается на 1. Во время изменения данной переменной необходимо заблокировать сигнал, поскольку она используется совместно основным циклом и обработчиком сигнала. Также необходимо, чтобы сигнал
SIGIO
был заблокирован, когда в начале цикла происходит проверка переменной
nqueue
.

Альтернативным способом является удаление обоих вызовов функции

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

Листинг 25.3. Обработчик сигнала SIGIO

//sigio/dgecho01.c

57 static void

58 sig_io(int signo)

59 {

60 ssize_t len;

61 int nread;

62 DG *ptr;

63 for (nread = 0;;) {

64 if (nqueue >= QSIZE)

65 err_quit("receive overflow");

66 ptr = &dg[iput];

67 ptr->dg_salen = clilen;

68 len = recvfrom(sockfd, ptr->dg_data, MAXDG, 0,

69 ptr->dg_sa, &ptr->dg_salen);

70 if (len < 0) {

71 if (errno == EWOULDBLOCK)

72 break; /* все сделано; очередь на чтение отсутствует */

73 else

74 err_sys("recvfrom error");

75 }

76 ptr->dg_len = len;

77 nread++;

78 nqueue++;

79 if (++iput >= QSIZE)

80 iput = 0;

81 }

82 cntread[nread]++; /*
гистограмма количества дейтаграмм.

считанных для каждого сигнала */

83 }

Во время создания этих обработчиков сигналов была обнаружена следующая проблема: в стандарте POSIX сигналы обычно непомещаются в очередь. Это означает, что если во время пребывания внутри обработчика сигналов (при этом сигнал заведомо заблокирован) возникает еще два сигнала, то сигнал доставляется еще одинраз.

ПРИМЕЧАНИЕ

В стандарте POSIX предусмотрено несколько сигналов реального времени, для которых обеспечивается буферизация, однако ряд других сигналов, в том числе и SIGIO, обычно не буферизуются, то есть не помещаются в очередь на доставку.

Рассмотрим следующий сценарий. Прибывает дейтаграмма и выдается сигнал. Обработчик сигнала считывает дейтаграмму и помещает ее в очередь к основному циклу. Но во время работы обработчика сигнала приходят еще две дейтаграммы, вызывая генерацию сигнала еще дважды. Поскольку сигнал блокирован, то когда обработчик сигналов возвращает управление после обработки первого сигнала, он запустится снова всего лишь один раз. После второго запуска обработчик считывает вторую дейтаграмму, а третья будет оставлена в очереди приходящих дейтаграмм сокета. Эта третья дейтаграмма будет прочитана, только если (и только когда) придет четвертая. Когда придет четвертая дейтаграмма, считана и поставлена в очередь на обработку основным циклом будет именно третья, а не четвертая дейтаграмма.

Поскольку сигналы не помещаются в очередь, дескриптор, установленный для управляемого сигналом ввода-вывода, обычно переводится в неблокируемый режим. Обработчик сигнала

SIGIO
мы кодируем таким образом, чтобы он считывал дейтаграммы в цикле, который прерывается, только когда при считывании возвращается ошибка
EWOULDBLOCK
.

Проверка переполнения очереди

64-65
Если очередь переполняется, происходит завершение работы. Для обработки такой ситуации существуют и другие способы (например, можно размещать в памяти дополнительные буферы), но для данного примера достаточно простого завершения.

Чтение дейтаграммы

66-76
На неблокируемом сокете вызывается функция
recvfrom
. Элемент массива, обозначенный индексом
iput
, — это то место, куда записывается дейтаграмма. Если нет дейтаграмм, которые нужно считывать, мы выходим из цикла
for
с помощью оператора
break
.

Увеличение счетчиков и индекса на единицу

77-80
Переменная
nread
является диагностическим счетчиком количества дейтаграмм, читаемых на один сигнал. Переменная
nqueue
— это количество дейтаграмм для обработки основным циклом.

Поделиться:
Популярные книги

Я все еще граф. Книга IX

Дрейк Сириус
9. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я все еще граф. Книга IX

Кодекс Крови. Книга VIII

Борзых М.
8. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VIII

Огненный князь

Машуков Тимур
1. Багряный восход
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Огненный князь

Ученичество. Книга 1

Понарошку Евгений
1. Государственный маг
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ученичество. Книга 1

Деспот

Шагаева Наталья
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Деспот

Инцел на службе демоницы 1 и 2: Секса будет много

Блум М.
Инцел на службе демоницы
Фантастика:
фэнтези
5.25
рейтинг книги
Инцел на службе демоницы 1 и 2: Секса будет много

Тринадцатый

NikL
1. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
6.80
рейтинг книги
Тринадцатый

Кодекс Охотника. Книга XIII

Винокуров Юрий
13. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
аниме
7.50
рейтинг книги
Кодекс Охотника. Книга XIII

Чехов. Книга 3

Гоблин (MeXXanik)
3. Адвокат Чехов
Фантастика:
альтернативная история
5.00
рейтинг книги
Чехов. Книга 3

Изменить нельзя простить

Томченко Анна
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Изменить нельзя простить

Сирота

Ланцов Михаил Алексеевич
1. Помещик
Фантастика:
альтернативная история
5.71
рейтинг книги
Сирота

Делегат

Астахов Евгений Евгеньевич
6. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Делегат

Эйгор. В потёмках

Кронос Александр
1. Эйгор
Фантастика:
боевая фантастика
7.00
рейтинг книги
Эйгор. В потёмках

Наследник с Меткой Охотника

Тарс Элиан
1. Десять Принцев Российской Империи
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Наследник с Меткой Охотника