Использование функций sigsetjmp и siglongjmp
Использование функций sigsetjmp и siglongjmp
Нашу проблему можно решить корректно, если отказаться от прерывания блокированного системного вызова обработчиком сигнала, вместо этого вызвав из обработчика сигнала функцию siglongjmp. Этот метод называется нелокальным оператором goto (nonlocal goto), поскольку мы можем использовать его для перехода из одной функции в другую. В листинге 20.5 проиллюстрирована эта технология.
Листинг 20.5. Вызов функций sigsetjmp и siglongjmp из обработчика сигнала
//bcast/dgclibcast5.c
1 #include "unp.h"
2 #include <setjmp.h>
3 static void recvfrom_alarm(int);
4 static sigjmp_buf jmpbuf;
5 void
6 dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
7 {
8 int n;
9 const int on = 1;
10 char sendline[MAXLINE], recvline[MAXLINE + 1];
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 Signal(SIGALRM, recvfrom_alarm);
16 while (Fgets(sendline, MAXLINE, fp) != NULL) {
17 Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
18 alarm(5);
19 for (;;) {
20 if (sigsetjmp(jmpbuf, 1) != 0)
21 break;
22 len = servlen;
23 n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
24 recvline[n] = 0; /* null terminate */
25 printf("from %s: %s",
26 Sock_ntop_host(preply_addr, len), recvline);
27 }
28 }
29 free(preply_addr);
30 }
31 static void
32 recvfrom_alarm(int signo)
33 {
34 siglongjmp(jmpbuf, 1);
35 }
Размещение буфера перехода в памяти
4 Мы выделяем буфер перехода, который будет использовать наша функция и ее обработчик сигнала.
Вызов функции sigsetjmp
20-23 Когда мы вызываем функцию sigsetjmp непосредственно из нашей функции dg_cli, она устанавливает буфер перехода и возвращает нуль. Мы продолжаем работать дальше и вызываем функцию recvfrom.
Обработка сигнала SIGALRM и вызов функции siglongjmp
31-35 Когда сигнал доставлен, мы вызываем функцию siglongjmp. Это заставляет sigsetjmp в функции dg_cli возвратить значение, равное второму аргументу (1), который должен быть ненулевым. Это приведет к завершению цикла for в функции dg_cli.
Использование функций sigsetjmp и siglongjmp подобным образом гарантирует, что мы не останемся навсегда блокированы в вызове функции recvfrom из-за доставки сигнала в неподходящее время. Однако такое решение создает иную потенциальную проблему. Если сигнал доставляется в тот момент, когда функция printf осуществляет вывод данных, управление будет передано из printf обратно на sigsetjmp. При этом в структурах данных printf могут возникнуть противоречия. Чтобы предотвратить эту проблему, следует объединить блокирование и разблокирование сигналов, показанное в листинге 20.2, с помощью нелокального оператора goto.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
9.1.6.2. Использование функций BSD: wait3() и wait4()
9.1.6.2. Использование функций BSD: wait3() и wait4() Системные вызовы BSD wait3() и wait4() полезны, если вы интересуетесь ресурсами, использованными порожденным процессом. Функции нестандартны (что означает, что они не являются частью POSIX), но широко доступны, в том числе на GNU/Linux. Объявления
ГЛАВА 2 Использование файловой системы и функций символьного ввода/вывода Windows
ГЛАВА 2 Использование файловой системы и функций символьного ввода/вывода Windows Нередко самыми первыми средствами операционной системы (ОС), с которыми разработчик сталкивается в любой системе, являются файловая система и простой терминальный ввод/вывод. Ранние ОС для PC,
Пример: использование функций gethostbyname и getservbyname
Пример: использование функций gethostbyname и getservbyname Теперь мы можем изменить код нашего TCP-клиента времени и даты, показанный в листинге 1.1, так, чтобы использовать функции gethostbyname и getservbyname и принимать два аргумента командной строки: имя узла и имя службы. Наша программа
Использование функций в операторах присваивания
Использование функций в операторах присваивания Поскольку функции и создаваемые вами процедуры типа Function возвращают значения, их тоже можно использовать в операторах присваивания. Например:ctrFavorite = InputBox(Кто сегодня фаворит?)В данном случае используется функция VBA Input Box,
Использование в scoqe встроенных функций
Использование в scoqe встроенных функций Независимо от того, пишете ли вы собственную функцию или процедуру Sub, не стесняйтесь призывать на помощь широчайшие возможности встроенных функций Excel по анализу данных и проведению вычислений. Использовать их в своем собственном
Правило 30: Тщательно обдумывайте использование встроенных функций
Правило 30: Тщательно обдумывайте использование встроенных функций Встроенные функции – какая замечательная идея! Они выглядят подобно функциям, они работают подобно функциям, они намного лучше макросов (см. правило 2). Их можно вызывать, не опасаясь накладных расходов,
Использование функций
Использование функций Программа Excel содержит огромное количество функций: математических, статистических, инженерных, логических, текстовых, финансовых и т. д. Эти функции вы можете использовать для создания формул или обработки данных таблицы.В данном разделе действие
Совет 46. Передавайте алгоритмам объекты функций вместо функций
Совет 46. Передавайте алгоритмам объекты функций вместо функций Часто говорят, что повышение уровня абстракции языков высокого уровня приводит к снижению эффективности сгенерированного кода. Александр Степанов, изобретатель STL, однажды разработал небольшой комплекс
ИЗУЧЕНИЕ И ИСПОЛЬЗОВАНИЕ ФУНКЦИЙ printf( ) И scanf( )
ИЗУЧЕНИЕ И ИСПОЛЬЗОВАНИЕ ФУНКЦИЙ printf( ) И scanf( ) Функции printf( ) и scanf( ) дают нам возможность взаимодействовать с программой. Мы называем их функциями ввода-вывода. Это не единственные функции, которыми мы можем воспользоваться для ввода и вывода данных с помощью
12.3.5. Адаптеры функций для объектов-функций
12.3.5. Адаптеры функций для объектов-функций В стандартной библиотеке имеется также ряд адаптеров функций, предназначенных для специализации и расширения как унарных, так и бинарных объектов-функций. Адаптеры – это специальные классы, разбитые на следующие две
19.11.2. Вызов функций из файла функций
19.11.2. Вызов функций из файла функций Мы уже рассматривали, каким образом функции вызываются из командной строки. Эти типы функций обычно используются утилитами, создающими системные сообщения.А теперь воспользуемся снова описанной выше функцией, но в этом случае
5.2.7. Использование функций в формулах
5.2.7. Использование функций в формулах Функцией называется операция, используемая в формуле, которая производит какие-либо действия с содержимым ячеек: вычисления, манипуляции с датами, со строками текста и т. п. Numbers включает 168 функций.Каждая функция состоит из имени и