Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

15.1.2. Остановка процессов

Четыре сигнала перемещают работающий процесс в состояние останова.

SIGSTOP
никогда не генерируется ядром. Он предназначен для остановки произвольных процессов. Его невозможно захватить или проигнорировать; он всегда останавливает целевой процесс. Остальные три сигнала, останавливающие процессы —
SIGTSTP
,
SIGTTIN
и
SIGTTOU
— могут генерироваться терминалом, на котором работает процесс, или другим процессом. Хотя эти сигналы ведут себя похожим образом, они генерируются при разных обстоятельствах.

SIGTSTP

Этот сигнал передается каждому процессу группы процессов переднего плана, когда пользователь нажимает клавиатурную комбинацию приостановки терминала [106] .

SIGTTIN

Когда фоновый процесс пытается считывать из терминала, ему передается

SIGTTIN
.

SIGTTOU

Этот сигнал обычно генерируется фоновым процессом, пытающимся выполнить запись в свой терминал. Сигнал генерируется только в случае установки атрибута терминала

TOSTOP
, как рассматривается в главе 16.

106

Обычно клавиатурной комбинацией приостановки является <Ctrl+Z>. Программа stty позволяет пользователям менять эту комбинацию. Подробнее это рассматривается в главе 16.

Данный сигнал генерируется также фоновым процессом, вызывающим

tcflush
,
tcflow
,
tcsetattr
,
tcsetpgrp
,
tcdrain
или
tcsendbreak
.

Действием по умолчанию каждого из этих трех сигналов является останов процесса. Все эти процессы можно поймать или игнорировать. В обоих случаях процесс не останавливается.

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, "получен SIGTSTP\n", 12);

13: catchSignal(SIGTSTP, 1);

14: kill(getpid, SIGTSTP);

15: } else {

16: write(STDOUT_FILENO, "получен SIGCONT\n", 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:

  • Читать дальше
  • 1
  • ...
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: