Книга: Разработка приложений в среде Linux. Второе издание
12.7.2. Отправка данных с сигналом
12.7.2. Отправка данных с сигналом
Механизм siginfo_t
также позволяет сигналам, которые посылают программы, присоединять к себе один элемент данных (этот элемент может быть указателем, что позволяет неявно передавать любой необходимый объем данных). Чтобы отправить данные, используется union sigval
.
#include <signal.h>
union sigval {
int sival_int;
void *sival_ptr;
};
Любой из членов объединения — sival_int
или sival_ptr
— может быть установлен в требуемое значение, которое включается в siginfo_t
, доставляемое вместе с сигналом. Чтобы сгенерировать сигнал с union sigval
, должна использоваться функция sigqueue()
.
#include <signal.h>
void *sigqueue(pid_t pid, int signum, const union sigval value);
В отличие от kill()
, pid
должен быть корректным идентификатором процесса (отрицательные значения не допускаются), signum
указывает номер посылаемого сигнала. Подобно kill()
, sigqueue()
допускает нулевое значение signum
нулю, чтобы проверить, позволяет ли вызывающий процесс посылать целевому сигналы, в действительности не выполняя такой посылки. Последний параметр, value
, представляет собой элемент данных, передаваемый вместе с сигналом.
Чтобы принять union sigval
, процесс, перехватывающий сигнал, должен использовать SA_SIGINFO
при регистрации обработчика сигналов с помощью sigaction()
. Когда член si_code
структуры siginfo_t
равен SI_QUEUE
, то siginfo_t
представляет член si_value
, который содержит значение value
, переданное sigqueue
.
Ниже приведен пример отправки элемента данных с сигналом. Он устанавливает в очередь три сигнала SIGRTMIN
с разными элементами данных. Он демонстрирует, что сигналы доставляются в том же порядке, что были отправлены, как мы и ожидаем при работе с сигналами реального времени[73]. Более сложный пример, использующий сигналы для отслеживания изменений в каталогах, можно найти в главе 14.
1: /* sigval.с */
2:
3: #include <sys/signal.h>
4: #include <stdlib.h>
5: #include <stdio.h>
6: #include <string.h>
7: #include <unistd.h>
8:
9: /* Захватить сигнал и зарегистрировать факт его обработки */
10: void handler(int signo, siginfo_t *si, void *context) {
11: printf("%dn", si->si_value.sival_int);
12: }
13:
14: int main() {
15: sigset_t mask;
16: sigset_t oldMask;
17: struct sigaction act;
18: int me = getpid();
19: union sigval val;
20:
21: /* Отправить сигналы handler() и сохранять все сигналы заблокированными,
22: чтобы handler() был сконфигурирован для перехвата с исключением
23: состязаний при манипулировании глобальными переменными */
24: act.sa_sigaction = handler;
25: act.sa_mask = mask;
26: act.sa_flags = SA_SIGINFO;
27:
28: sigaction(SIGRTMIN, &act, NULL);
29:
30: /* Блокировать SIGRTMIN, чтобы можно было увидеть очередь и упорядочение*/
31: sigemptyset(&mask);
32: sigaddset(&mask, SIGRTMIN);
33:
34: sigprocmask(SIG_BLOCK, &mask, &oldMask);
35:
36: /* Сгенерировать сигналы */
37: val.sival_int = 1;
38: sigqueue(me, SIGRTMIN, val);
39: val.sival_int++;
40: sigqueue(me, SIGRTMIN, val);
41: val.sival_int++;
42: sigqueue(me, SIGRTMIN, val);
43:
44: /* Разрешить доставку сигналов */
45: sigprocmask(SIG_SETMASK, &oldMask, NULL);
46:
47: return 0;
48: }
- Резервное копирование базы данных InterBase
- Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
- Резервное копирование многофайловых баз данных
- Восстановление из резервных копий многофайловых баз данных
- Владелец базы данных
- ЧАСТЬ IV. База данных и ее объекты.
- Перевод базы данных InterBase 6.x на 3-й диалект
- Типы данных для работы с датой и временем
- Практическая работа 53. Запуск Access. Работа с объектами базы данных
- Обзор основных причин повреждения базы данных
- Ошибки проектирования базы данных
- Профилактика повреждений баз данных InterBase