Книга: Разработка приложений в среде Linux. Второе издание
15.1.3. Обработка сигналов управления заданиями
15.1.3. Обработка сигналов управления заданиями
Хотя многие приложения можно останавливать и перезапускать без побочных эффектов, другим процессам требуется обрабатывать состояния останова и запуска. Например, большинству редакторов необходимо модифицировать параметры терминала в рабочем состоянии. Когда пользователи приостанавливают процесс, они ожидают, что их терминал восстановит свое состояние по умолчанию.
Когда процессу нужно выполнять действия перед приостановкой, должен быть предусмотрен обработчик сигнала для SIGTSTP
. Это позволяет ядру уведомлять процесс о необходимости приостановки.
При получении SIGTSTP
процесс должен немедленно выполнить все необходимые ему действия, чтобы разрешить приостановку (например, восстановление исходного состояния терминала) и приостановиться самому. Самый простой способ приостановки процесса — передача самому себе сигнала SIGSTOP
. Однако большинство оболочек отображают сообщения с типом сигнала, вызвавшего остановку процесса, и если процесс передаст себе sigstop, он будет отличаться от большинства приостановленных процессов. Во избежание этого неудобства многие приложения сбрасывают свой обработчик SIGTSTP
в SIG_DFL
и передают себе SIGTSTP
.
Процессам, которые требуют специальный код для правильных приостановок, обычно необходимо выполнять специальные действия при перезапуске. Это легко делается предоставлением обработчика сигнала для SIGCONT
, который выполняет такие действия. Если процесс приостанавливается с помощью SIGTSTP
, такие специальные действия, возможно, включают установку обработчика сигнала для SIGTSTP
.
Ниже приведен код простого обработчика сигналов SIGCONT
и SIGTSTP
. Когда пользователь приостанавливает или перезапускает процесс, последний отображает сообщение перед остановкой или продолжением.
1: /* monitor.с */
2:
3: #include <signal.h>
4: #include <stdio.h>
5: #include <string.h>
6: #include <unistd.h>
7:
8: void catchSignal(int sigNum, int useDefault);
9:
10: void handler(int signum) {
11: if (signum == SIGTSTP) {
12: write(STDOUT_FILENO, "получен SIGTSTPn", 12);
13: catchSignal(SIGTSTP, 1);
14: kill(getpid(), SIGTSTP);
15: } else {
16: write(STDOUT_FILENO, "получен SIGCONTn", 12);
17: catchSignal(SIGTSTP, 0);
18: }
19: }
20:
21: void catchSignal(int sigNum, int useDefault) {
22: struct sigaction sa;
23:
24: memset(&sa, 0, sizeof(sa));
25:
26: if (useDefault)
27: sa.sa_handler = SIG_DFL;
28: else
29: sa.sa_handler = handler;
30:
31: if (sigaction(sigNum, &sa, NULL)) perror("sigaction");
32: }
33:
34: int main() {
35: catchSignal(SIGTSTP, 0);
36: catchSignal(SIGCONT, 0);
37:
38: while(1);
39:
40: return 0;
41: }
- Регистр управления 16-разрядным вычитающим счетчиком
- 2.2. Базовая обработка командной строки
- Часть IV. Стиль парадоксального управления Samsung и будущее концепции «Путь Samsung»
- 8 Рендеринг (визуализация) и обработка изображений
- Глава 4 Особенности корпоративного управления в условиях электронного банкинга
- 5.6. Обработка событий в сборных видах
- 11.2. Обработка задержек при асинхронных соединениях
- Глава 20 Консольные инструменты управления пакетами
- Рис. 77. Вид по категориям панели управления.
- Самые страшные ошибки управления эффективностью
- 13.6.3. Взаимодействие с модулями расширения и элементами управления ActiveX
- 15.1. Основы управления заданиями