13: int nextSig = 0;

14: int sigOrder[10];

15:

16: /* Перехватить сигнал и записать, что он был обработан */

17: void handler(int signo) {

18:  sigOrder[nextSig++] = signo;

19: }

20:

21: int main() {

22:  sigset_t mask;

23:  sigset_t oldMask;

24:  struct sigaction act;

25:  int i;

26:

27:  /* Обрабатываемые в программе сигналы */

28:  sigemptyset(&mask);

29:  sigaddset(&mask, SIGRTMIN);

30:  sigaddset(&mask, SIGRTMIN+1);

31:  sigaddset(&mask, SIGUSR1);

32:

33:  /* Отправить сигнал handler() и сохранять их блокированными,

34:     чтобы handler() был сконфигурирован во избежание

35:     состязаний при манипулировании глобальными переменными */

36:  act.sa_handler = handler;

37:  act.sa_mask = mask;

38:  act.sa_flags = 0;

39:

40:  sigaction(SIGRTMIN, &act, NULL);

41:  sigaction(SIGRTMIN+1, &act, NULL);

42:  sigaction(SIGUSR1, &act, NULL);

43:

44:  /* Блокировать сигналы, с которыми мы работаем, чтобы

45:     была видна очередность и порядок */

46:  sigprocmask(SIG_BLOCK, &mask, &oldMask);

47:

48:  /* Генерировать сигналы */

49:  raise(SIGRTMIN+1);

50:  raise(SIGRTMIN);

51:  raise(SIGRTMIN);

52:  raise(SIGRTMIN+1);

53:  raise(SIGRTMIN);

54:  raise(SIGUSR1);

55:  raise(SIGUSR1);

56:

57:  /* Разрешить доставку этих сигналов. Все они будут доставлены

58:     прямо перед возвратом этого вызова (для Linux; это

59:     НЕПЕРЕНОСИМОЕ поведение). */

60:  sigprocmask(SIG_SETMASK, &oldMask, NULL);

61:

62:  /* Отобразить упорядоченный список перехваченных сигналов */

63:  printf('Принятые сигналы: ');

64:  for (i = 0; i < nextSig; i++)

65:   if (sigOrder[i] < SIGRTMIN)

66:    printf(' %s ', strsignal(sigOrder[i]));

67:   else

68:    printf(' SIGRTMIN + %d ', sigOrder[i] - SIGRTMIN);

69:

70:  return 0;

71: }

Эта программа посылает себе некоторое количество сигналов и выводит на дисплей порядок их получения. Когда сигналы отправляются, она блокирует их, чтобы предотвратить немедленную доставку. Также она блокирует сигналы всякий раз, когда вызывается обработчик, устанавливая значение члена sa_mask структуры struct sigaction при настройке обработчика для каждого сигнала. Это предотвращает возможное состояние состязаний при обращении к глобальным переменным nextSig и sigOrder изнутри обработчика.

Запуск этой программы выдаст показанные ниже результаты.

Принятые сигналы:

        User defined signal1

        SIGRTMIN + 0

        SIGRTMIN + 0

        SIGRTMIN + 0

        SIGRTMIN + 1

        SIGRTMIN + 1

Это показывает, что все сигналы реального времени были доставлены, в то же время, был доставлен только один экземпляр сигнала SIGUSR1. Вы также видите изменение порядка сигналов реального времени — все сигналы SIGRTMIN были доставлены перед SIGRTMIN + 1.

12.7. Дополнительные сведения о сигналах

Сигналы, которые мы обсуждали до сих пор, не несли в себе никаких данных; появление сигнала — это единственная информация, которую получает приложение. В некоторых случаях было бы неплохо знать, что послужило причиной отправки сигнала (как, например, неправильная адресация памяти, генерирующая SIGSEGV), или же иметь возможность включить данные в сигналы, генерируемые приложением. Расширение реального времени Real Time Signals позволяет решить обе эти задачи.

12.7.1. Получение контекста сигнала

Информация о том, как и почему был сгенерирован сигнал, называется контекстом[68] сигнала. Приложения, которые должны видеть этот контекст, используют обработчики сигналов, отличающиеся от нормальных. Они включают два дополнительных параметра — указатель на siginfo_t, предоставляющий контекст сигнала, и указатель на void*, который может быть использован некоторыми низкоуровневыми

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату