- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания UNIX: взаимодействие процессов - Уильям Стивенс
Шрифт:
Интервал:
Закладка:
//rtsignals/test1.c
1 #include "unpipc.h"
2 static void sig_rt(int, siginfo_t *, void *);
3 int
4 main(int argc, char **argv)
5 {
6 int i, j;
7 pid_t pid;
8 sigset_t newset;
9 union sigval val;
10 printf("SIGRTMIN = %d, SIGRTMAX = %dn", (int) SIGRTMIN, (int) SIGRTMAX);
11 if ((pid = Fork()) == 0) {
12 /* дочерний процесс блокирует 3 сигнала */
13 Sigemptyset(&newset);
14 Sigaddset(&newset, SIGRTMAX);
15 Sigaddset(&newset, SIGRTMAX – 1);
16 Sigaddset(&newset, SIGRTMAX – 2);
17 Sigprocmask(SIG_BLOCK, &newset, NULL);
18 /* установка обработчика с флагом SA_SIGINFO */
19 Signal_rt(SIGRTMAX, sig_rt);
20 Signal_rt(SIGRTMAX – 1, sig_rt);
21 Signal_rt(SIGRTMAX – 2, sig_rt);
22 sleep(6); /* родительский процесс посылает все сигналы */
23 Sigprocmask(SIG UNBLOCK, &newset, NULL); /* разблокируемся */
24 sleep(3); /* получаем сигналы */
25 exit(O);
26 }
27 /* родительский процесс отправляет сигналы */
28 sleep(3); /* дочерний процесс блокирует сигналы */
29 for (i = SIGRTMAX; i >= SIGRTMAX – 2; i--) {
30 for (j = 0; j <= 2; j++) {
31 val.sival_int = j;
32 Sigqueue(pid, i, val);
33 printf("sent signal %d, val = %dn", i, j);
34 }
35 }
36 exit(0);
37 }
38 static void
39 sig_rt(int signo, siginfo_t *info, void *context)
40 {
41 printf(received signal #%d, code = %d, ival = %dn",
42 signo.info->si_code, info->si_value.sival_int);
43 }
Вывод номеров сигналов реального времени10 Мы печатаем наибольший и наименьший номера сигналов реального времени, чтобы узнать, сколько их предоставляется в данной реализации. Мы преобразуем обе константы к типу integer, поскольку в некоторых реализациях они определяются как макросы, требующие вызова sysconf, например:
#define SIGRTMAX (sysconf(_SC_RTSIG_MAX))
и функция sysconf возвращает целое типа long (см. упражнение 5.4).
Вызов fork и блокирование трех сигналов реального времени11-17 Запускается дочерний процесс, который вызывает sigprocmask для блокировки трех используемых сигналов реального времени: SIGRTMAX, SIGRTMAX-1 и SIGRTMAX-2.
Установка обработчика сигнала18-21 Мы вызываем функцию signal_rt (приведенную в листинге 5.15) для установки функции sig_rt в качестве обработчика трех указанных выше сигналов реального времени. Функция устанавливает флаг SA_SIGINFO, и поскольку эти три сигнала являются сигналами реального времени, мы можем ожидать, что они будут обрабатываться соответствующим образом. Эта функция также устанавливает маску сигналов, блокируемых на время выполнения обработчика.
Ожидание порождения сигналов родительским процессом, разблокирование сигналов22-25 Дочерний процесс ждет 6 секунд, пока родительский породит девять сигналов. Затем вызывается sigprocmask для разблокирования трех сигналов реального времени. Это позволяет всем помещенным в очередь сигналам достичь адресата. Затем делается пауза еще на три секунды, чтобы обработчик успел вызвать printf девять раз, после чего дочерний процесс завершает свою работу.
Родительский процесс отправляет девять сигналов27-36 Родительский процесс ждет три секунды, пока дочерний не заблокирует все требуемые сигналы. Затем родительский процесс порождает три экземпляра каждого из трех сигналов реального времени: i принимает 3 значения, a j принимает значения 0, 1 и 2 для каждого из значений i. Мы преднамеренно порождаем сигналы начиная с наибольшего номера, поскольку ожидаем, что они будут получены начиная с наименьшего. Мы также отсылаем с каждым из сигналов новое значение sigval_int, чтобы проверить, что копии одного и того же сигнала доставляются в том же порядке, в каком они были отправлены, то есть очередь действительно является очередью.
Обработчик сигнала38-43 Обработчик сигнала просто выводит информацию о полученном сигнале.
ПРИМЕЧАНИЕ
Из табл. 5.1 следует, что функция printf не относится к функциям типа async-signal-safe и не должна вызываться из обработчика сигналов. Здесь мы используем ее исключительно в качестве проверочного средства в маленькой тестовой программе.
Запустим эту программу в Solaris 2.6. Результат будет не тем, которого мы ожидали:
solaris % test1
SIGRTMIN = 38, SIGRTMAX = 45 8 сигналов реального времени
трехсекундная пауза
sent signal 45, val = 0
sent signal 45, val = 1
sent signal 45, val = 2
sent signal 44, val = 0
sent signal 44, val = 1
sent signal 44, val = 2
sent signal 43, val = 0
sent signal 43, val = 1
sent signal 43, val = 2
solaris % родительский процесс завершил работу, пауза 3 секунды,
пока дочерний процесс не разблокирует сигналы
received signal #45, code = –2, ival = 2 дочерний процесс получает сигналы
received signal #45, code = –2, ival = 1
received signal #45, code = –2, ival = 0
received signal #44, code = –2, ival = 2
received signal #44, code = –2, ival = 1
received signal #44, code = –2, ival = 0
received signal #43, code = –2, ival = 2
received signal #43, code = –2, ival = 1
received signal #43, code = –2, ival = 0
В очередь помещаются девять сигналов, но первыми принимаются сигналы с большими номерами (а мы ожидали получить сигналы с меньшими номерами).
Кроме того, сигналы с одинаковым номером приходят в порядке LIFO, а не FIFO. Код si_code = –2 соответствует SI_QUEUE.
Запустив программу в Digital Unix 4.0B, мы получим именно тот результат, которого ожидали:
alpha % test1
SIGRTMIN = 33, SIGRTMAX = 48 16 сигналов реального времени
трех секундная пауза
sent signal 48, val = 0
sent signal 48, val = 1
sent signal 48, val = 2
sent signal 47, val = 0
sent signal 47, val = 1
sent signal 47, val = 2
sent signal 46, val = 0
sent signal 46, val = 1
sent signal 46, val = 2
alpha % родительский процесс завершил работу, пауза 3 секунды.
пока дочерний процесс не разблокируетсигналы
received signal #46, code – –1, ival = 0 дочерний процесс получает сигналы
received signal #46, code = –1, ival = 1
received signal #46, code = –1, ival = 2
received signal #47, code – –1, ival = 0
received signal #47, code = –1, ival = 1
received signal #47, code = –1, ival = 2
received signal #48, code = –1, ival = 0
received signal #48, code = –1, ival = 1
received signal #48, code = –1, ival = 2
Девять сигналов помещаются в очередь и получаются адресатом в ожидаемом порядке: первым приходит сигнал с меньшим номером, а копии сигнала приходят в порядке FIFO.
ПРИМЕЧАНИЕ
Похоже, что в реализации Solaris 2.6 есть ошибка.
Функция signal_rt
В книге [24, с. 120] мы привели пример собственной функции signal, вызывавшей функцию sigaction стандарта Posix для установки обработчика сигнала, обеспечивающего надежную семантику Posix. Изменим эту функцию, чтобы обеспечить поддержку реального времени. Новую функцию мы назовем signal_rt; ее текст приведен в листинге 5.15.
Листинг 5.15. Функция signal_rt с поддержкой реального времени//lib/signal_rt.c
1 #include "unpipc.h"
2 Sigfunc_rt *
3 signal_rt(int signo, Sigfunc_rt *func)
4 {
5 struct sigaction act, oact;
6 act.sa_sigaction = func; /* сохраняем адрес функции */
7 sigemptyset(&act.sa_mask);
8 act.sa_flags = SA_SIGINFO; /* гарантирует режим реального времени */
9 if (signo == SIGALRM) {
10 #ifdef SA_INTERRUPT
11 act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
12 #endif
13 } else {
14 #ifdef SA_RESTART
15 act.sa_flags |= SA_RESTART; /* SVR4, 44BSD */
16 #endif
17 }
18 if (sigaction(signo, &act, &oact) < 0)
19 return((Sigfunc_rt *) SIG_ERR);
20 return(oact.sa_sigaction);
21 }
Упрощение прототипа функции с использованием typedef1-3 В нашем заголовочном файле unpiрс.h (листинг В.1) мы определяем Sigfunc_rt как
typedef void Sigfunc_rt(int, siginfo_t*, void*);
Ранее в этом разделе мы говорили о том, что это прототип функции для обработчика сигнала, устанавливаемого с флагом SA_SIGINFO.
Указание функции-обработчикаСтруктура sigaction претерпела изменения с добавлением поддержки сигна-5-7 лов реального времени: к ней было добавлено новое поле sa_sigaction:
struct sigaction {
void (*sa_handler)(); /* SIG_DFL, SIG_IGN или адрес обработчика сигнала */