Пример: простая программа с уведомлением

Пример: простая программа с уведомлением

Прежде чем углубляться в тонкости сигналов реального времени и потоков Posix, мы напишем простейшую программу, включающую отправку сигнала SI6USR1 при помещении сообщения в пустую очередь. Эта программа приведена в листинге 5.8, и мы отметим, что она содержит ошибку, о которой мы вскоре поговорим подробно.

Листинг 5.8. Отправка sigusr1 при помещении сообщения в пустую очередь (неправильная версия программы)

//pxmsg/mqnotifysigl.c

1  #include "unpipc.h"

2  mqd_t mqd;

3  void *buff;

4  struct mq_attr attr;

5  struct sigevent sigev;

6  static void sig_usrl(int);

7  int

8  main(int argc, char **argv)

9  {

10  if (argc != 2)

11   err_quit("usage: mqnotifysig1 <name>");

12  /* открываем очередь, получаем атрибуты, выделяем буфер */

13  mqd = Mq_open(argv[1], O_RDONLY);

14  Mq_getattr(mqd, &attr);

15  buff = Malloc(attr.mq_msgsize);

16  /* устанавливаем обработчик, включаем уведомление */

17  Signal(SIGUSR1, sig_usr1);

18  sigev.sigev_notify = SIGEV_SIGNAL;

19  sigev.sigev_signo = SIGUSR1;

20  Mq_notify(mqd, &sigev);

21  for (;;)

22   pause(); /* все делает обработчик */

23  exit(0);

24 }

25 static void

26 sig_usr1(int signo)

27 {

28  ssize_t n;

29  Mq_notify(mqd, &sigev); /* сначала перерегистрируемся */

30  n = Mq_receive(mqd, buff, attr.mq_msgsize, NULL);

31  printf("SIGUSR1 received, read %ld bytes ", (long) n);

32  return;

33 }

Объявление глобальных переменных

2-6 Мы объявляем несколько глобальных переменных, используемых совместно функцией main и нашим обработчиком сигнала (sig_usr1).

Открытие очереди, получение атрибутов, выделение буфера чтения

12-15 Мы открываем очередь сообщений, получаем ее атрибуты и выделяем буфер считывания соответствующего размера.

Установка обработчика сигнала, включение уведомления

16-20 Сначала мы устанавливаем свой обработчик для сигнала SIGUSR1. Мы присваиваем полю sigev_notify структуры sigevent значение SIGEV_SIGNAL, что говорит системе о необходимости отправки сигнала, когда очередь из пустой становится непустой. Полю sigev_signo присваивается значение, соответствующее тому сигналу, который мы хотим получить. Затем вызывается функция mq_notify.

Бесконечный цикл

Функция main после этого зацикливается, и процесс приостанавливается при вызове pause, возвращающей –1 при получении сигнала.

Получение сигнала, считывание сообщения

Обработчик сигнала вызывает mq_notify для перерегистрации, считывает сообщение и выводит его длину. В этой программе мы игнорируем приоритет полученного сообщения. 

ПРИМЕЧАНИЕ

Оператор return в конце sig_usr1 не требуется, поскольку возвращаемое значение отсутствует, а конец текста функции неявно предусматривает возвращение в вызвавшую программу. Тем не менее автор всегда записывает return явно, чтобы указать, что возвращение из этой функции может происходит с особенностями. Например, может произойти преждевременный возврат (с ошибкой EINTR) в потоке, обрабатывающем сигнал. 

Запустим теперь эту программу в одном из окон

solaris % mqcreate /test1

solaris % mqnotifysig1 /test1

и затем выполним следующую команду в другом окне

solaris % mqsend /test1 50 16

Как и ожидалось, программа mqnotifysig1 выведет сообщение: SIGUSR1 received, read 50 bytes.

Мы можем проверить, что только один процесс может быть зарегистрирован на получение уведомления в любой момент, запустив копию пpoгрaммы в другом окне:

solaris % mqnotifysig1 /test1

mq_notify error: Device busy

Это сообщение соответствует коду ошибки EBUSY.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Пример: программа mqunlink

Из книги Системное программирование в среде Windows автора Харт Джонсон М

Пример: программа mqunlink В листинге 5.2 приведена программа mqunlink, удаляющая из системы очередь сообщений.Листинг 5.2. Удаление очереди из системы: mqunlink//pxmsg/mqunlink.c1 #include "unpipc.h"2 int3 main(int argc, char **argv)4 {5  if (argc != 2)6   err_quit("usage: mqunlink <name>");7  Mq_unlink(argv[1]);8  exit(0);9 }С помощью этой программы


Пример: программа mqgetattr

Из книги Программирование на языке Пролог для искусственного интеллекта автора Братко Иван

Пример: программа mqgetattr Программа из листинга 5.3 открывает указанную очередь сообщений и выводит значения ее атрибутов.Листинг 5.3. Получение и вывод значений атрибутов очереди сообщений//pxmsg/mqgetattr.c1  #include "unpipc.h"2  int3  main(int argc, char **argv)4  {5   mqd_t mqd;6   struct mq_attr attr;7   if (argc !=


Пример: программа mqsend

Из книги Искусство программирования на языке сценариев командной оболочки автора Купер Мендель

Пример: программа mqsend В листинге 5.5 приведен текст программы, помещающей сообщение в очередь.Листинг 5.5. Программа mqsend//pxmsg/mqsend.c1  #include "unpipc.h"2  int3  main(int argc, char **argv)4  {5   mqd_t mqd;6   void *ptr;7   size_t len;8   uint_t prio;9   if (argc != 4)10   err_quit("usage: mqsend <name> <#bytes> <priority>");11  len =


Пример: программа mqsysconf

Из книги автора

Пример: программа mqsysconf Программа в листинге 5.7 вызывает функцию sysconf и выводит два ограничения на очереди сообщений, определяемые реализацией.Листинг 5.7. Получение ограничений очередей с помощью sysconf//pxmsg/mqsysconf.с1 #include "unpipc.h"2 int3 main(int argc, char **argv)4 {5  printf("MQ_OPEN_MAX = %ld, MQ_PRIO_MAX =


Пример: программа semsysconf

Из книги автора

Пример: программа semsysconf Программа в листинге 10.20 вызывает sysconf и выводит два ограничения на семафоры, зависящие от конкретной реализации. Листинг 10.20. Вызов sysconf для получения ограничений на семафоры//pxsem/semsysconf.с1 #include "unpipc.h"2 int3 main(int argc, char **argv)4 {5  printf("SEM_NSEMS_MAX = %ld, SEM_VALUE_MAX =


Пример: перенос программы sortMM (программа 5.5)

Из книги автора

Пример: перенос программы sortMM (программа 5.5) В программе sortMM (программа 5.5) интенсивно используются указатели, и в частности, арифметика указателей. Подготовка этой программы к переносу, в результате чего ее можно будет компоновать и выполнять под управлением как Win32, так и


Пример 22-1. Простая функция

Из книги автора

Пример 22-1. Простая функция #!/bin/bashfunky (){ echo "Это обычная функция."} # Функция должна быть объявлена раньше, чем ее можно будет использовать. # Вызов функции.funkyexit 0Функция должна быть объявлена раньше, чем ее можно будет использовать. К сожалению, в Bash нет возможности


Пример A-3. rn: Очень простая утилита для переименования файлов

Из книги автора

Пример A-3. rn: Очень простая утилита для переименования файлов Этот сценарий является модификацией Пример 12-15.#! /bin/bash## Очень простая утилита для переименования файлов## Утилита "ren", автор Vladimir Lanin (lanin@csd2.nyu.edu),#+ выполняет эти же действия много лучше.ARGS=2E_BADARGS=65ONE=1 #