Блокирование и разблокирование сигнала с помощью функции pselect
Блокирование и разблокирование сигнала с помощью функции pselect
Одним из корректных решений будет использование функции pselect (см. раздел 6.9), как показано в листинге 20.3.
Листинг 20.3. Блокирование и разблокирование сигналов с помощью функции pselect
//bcast/dgclibcast4.с
1 #include "unp.h"
2 static void recvfrom_alarm(int);
3 void
4 dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
5 {
6 int n;
7 const int on = 1;
8 char sendline[MAXLINE], recvline[MAXLINE + 1];
9 fd_set rset;
10 sigset_t sigset_alrm, sigset_empty;
11 socklen_t len;
12 struct sockaddr *preply_addr;
13 preply_addr = Malloc(servlen);
14 Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
15 FD_ZERO(&rset);
16 Sigemptyset(&sigset_empty);
17 Sigemptyset(&sigset_alrm);
18 Sigaddset(&sigset_alrm, SIGALRM);
19 Signal(SIGALRM, recvfrom_alarm);
20 while (Fgets(sendline, MAXLINE, fp) != NULL) {
21 Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
22 Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);
23 alarm(5);
24 for (;;) {
25 FD_SET(sockfd, &rset);
26 n = pselect(sockfd + 1, &rset, NULL, NULL, NULL, &sigset_empty);
27 if (n < 0) {
28 if (errno == EINTR)
29 break;
30 else
31 err_sys("pselect error");
32 } else if (n != 1)
33 err_sys("pselect error; returned %d", n);
34 len = servlen;
35 n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
36 recvline[n] = 0; /* завершающий нуль */
37 printf("from %s: %s",
38 Sock_ntop_host(preply_addr, len), recvline);
39 }
40 }
41 free(preply_addr);
42 }
43 static void
44 recvfrom_alarm(int signo)
45 {
46 return; /* просто прерываем recvfrom() */
47 }
22-23 Мы блокируем сигнал SIGALRM и вызываем функцию pselect. Последний аргумент этой функции — указатель на нашу переменную sigset_empty, являющуюся набором сигналов, в котором нет блокированных сигналов (все сигналы разблокированы). Функция pselect сохранит текущую маску сигналов (которая блокирует SIGALRM), проверит заданные дескрипторы, заблокируется при необходимости с маской сигналов, установленной в пустой набор, но перед завершением функции маска сигналов процесса будет переустановлена в исходное значение, которое она имела при вызове функции pselect. Ключ к пониманию функции pselect в том, что установка маски сигналов, проверка дескрипторов и переустановка маски сигнала — это атомарные операции по отношению к вызывающему процессу.
34-38 Если наш сокет готов для чтения, мы вызываем функцию recvfrom, зная, что она не заблокируется.
Как мы упоминали в разделе 6.9, функция pselect — относительно новая среди других, описываемых спецификацией POSIX. Из всех систем, показанных на рис. 1.7, эту функцию поддерживают только FreeBSD и Linux. Тем не менее в листинге 20.4 представлена простая, хотя и некорректная ее реализация. Мы приводим ее здесь, несмотря на некорректность, чтобы продемонстрировать три стадии решения: установку маски сигнала в значение, заданное вызывающей функцией, с сохранением текущей маски, проверку дескрипторов и переустановку маски сигнала.
Листинг 20.4. Простая некорректная реализация функции pselect
//lib/pselect.c
9 #include "unp.h"
10 int
11 pselect(int nfds, fd_set *rset, fd_set *wset, fd_set *xset,
12 const struct timespec *ts, const sigset_t *sigmask)
13 {
14 int n;
15 struct timeval tv;
16 sigset_t savemask;
17 if (ts != NULL) {
18 tv.tv_sec = ts->tv_sec;
19 tv.tv_usec = ts->tv_nsec / 1000; /* наносекунды -> микросекунды */
20 }
21 sigprocmask(SIG_SETMASK, sigmask, &savemask); /* маска вызывающего
процесса */
22 n = select(nfds, rset, wset, xset., (ts == NULL) ? NULL : &tv);
23 sigprocmask(SIG_SETMASK, &savemask, NULL); /* восстанавливаем
исходную маску */
24 return (n);
25 }
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
Блокирование файлов
Блокирование файлов В системах, допускающих одновременное выполнение нескольких процессов, особую актуальность приобретает проблема координации и синхронизации доступа к разделяемым (совместно используемым) объектам, например файлам.В Windows имеется возможность
Традиционная обработка сигнала
Традиционная обработка сигнала В этой части изложения мы рассмотрим традиционные модели перехвата сигналов и установки для них собственных обработчиков (в том числе и игнорирование или восстановление стандартной обработки по умолчанию). Термин «традиционный» здесь
12.1.1. Жизненный цикл сигнала
12.1.1. Жизненный цикл сигнала Сигналы имеют четко определенный жизненный цикл: они создаются, сохраняются до тех пор, пока ядро не выполнит определенное действие на основе сигнала, а затем вызывают совершение этого действия. Создание сигнала называют по-разному: поднятие
12.7.1. Получение контекста сигнала
12.7.1. Получение контекста сигнала Информация о том, как и почему был сгенерирован сигнал, называется контекстом[68] сигнала. Приложения, которые должны видеть этот контекст, используют обработчики сигналов, отличающиеся от нормальных. Они включают два дополнительных
20.2. Выдача звукового сигнала
20.2. Выдача звукового сигнала Заставить консоль генерировать звуковой сигнал в течение определенного периода времени на указанной частоте совсем не сложное дело. Для этого существуют два способа. Первый состоит во включении или отключении постоянной тональной посылки.
11. Блокирование Tor и как с ним бороться
11. Блокирование Tor и как с ним бороться Система Tor позволяет скрывать от провайдера конечные (целевые) адреса, тем самым прорывая возможную блокаду доступа к заблокированным им сетевым ресурсам. Также система Tor скрывает от целевых ресурсов адрес отправителя, тем самым
Отправление сигнала
Отправление сигнала Ядро генерирует и отправляет процессу сигнал в ответ на ряд событий, которые могут быть вызваны самим процессом, другим процессом, прерыванием или какими-либо внешними событиями. Можно выделить основные причины отправки сигнала: Особые
Доставка и обработка сигнала
Доставка и обработка сигнала Для каждого сигнала в системе определена обработка по умолчанию, которую выполняет ядро, если процесс не указал другого действия. В общем случае существуют пять возможных действий: завершить выполнение процесса (с созданием образа core и без),
5.9. Обработка сигнала SIGCHLD
5.9. Обработка сигнала SIGCHLD Назначение состояния зомби — сохранить информацию о дочернем процессе, чтобы родительский процесс мог ее впоследствии получить. Эта информация включает идентификатор дочернего процесса, статус завершения и данные об использовании ресурсов
6.9. Функция pselect
6.9. Функция pselect Функция pselect была введена в POSIX и в настоящий момент поддерживается множеством версий Unix.#include <sys/select.h>#include <signal.h>#include <time.h>int pselect(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timespec *timeout, const sigset_t *sigmask);Возвращает: количество готовых дескрипторов, 0 в
Применение IPC в обработчике сигнала функции
Применение IPC в обработчике сигнала функции Существует еще один корректный путь решения нашей проблемы. Вместо того чтобы просто возвращать управление и, как мы надеемся, прерывать блокированную функцию recvfrom, наш обработчик сигнала при помощи средств IPC (Interprocess Communications
9.3. Блокирование записей с помощью fcntl по стандарту Posix
9.3. Блокирование записей с помощью fcntl по стандарту Posix Согласно стандарту Posix, интерфейсом для блокировки записей является функция fcntl:#include <fcntl.h>int fcntl(int fd, int cmd,… /* struct flock *arg */);/* Возвращает –1 в случае ошибки: результат, возвращаемый в случае успешного завершения,
9.9. Блокирование в NFS
9.9. Блокирование в NFS Аббревиатура NFS расшифровывается как Network File System (сетевая файловая система); эта система подробно обсуждается в главе 29 [22]. Блокировка записей fcntl представляет собой расширение NFS, поддерживаемое большинством ее реализаций. Обслуживается эта
26.2.2. Обнаружение сигнала
26.2.2. Обнаружение сигнала Некоторые сигналы можно захватить и выполнить соответствующие действия. Другие сигналы нельзя уловить. Например, если команда получает сигнал 9, пользователю не нужно предпринимать какие?либо действия.Если ограничиться написанием сценариев,
Конвертеры сигнала
Конвертеры сигнала Рассмотрим второй, очень важный компонент системы спутникового телевидения – конвертер сигнала. Конвертер представляет собой небольшой электронный блок, находящийся в фокусе спутниковой антенны. Он собирает сигнал, отраженный от зеркала тарелки,