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

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.

<p>Сигналы Posix: функции типа Async-Signal-Safe</p>

Недостаток пpoгрaммы из листинга 5.8 в том, что она вызывает mq_notify, mq_receive и printf из обработчика сигнала. Ни одну из этих функций вызывать оттуда не следует.

Функции, которые могут быть вызваны из обработчика сигнала, относятся к группе, называемой, согласно Posix, async-signal-safe functions (функции, обеспечивающие безопасную обработку асинхронных сигналов). В табл. 5.1 приведены эти функции по стандарту Posix вместе с некоторыми дополнительными, появившимися только в Unix 98.

Функции, которых нет в этом списке, не должны вызываться из обработчика сигнала. Обратите внимание, что в списке отсутствуют стандартные функции библиотеки ввода-вывода и функции pthread_XXX для работы с потоками. Из всех функций IPC, рассматриваемых в этой книге, в список попали только sem_post, read и write (подразумевается, что последние две используются с программными каналами и FIFO).

ПРИМЕЧАНИЕ

Стандарт ANSI С указывает четыре функции, которые могут быть вызваны из обработчика сигналов: abort, exit, longjmp, signal. Первые три отсутствуют в списке функций async-signal-safe стандарта Unix 98. 

Таблица 5.1. Функции, относящиеся к группе async-signal-safe

access        fpathconf rename      sysconf

aio_return    fstat     rmdir       tcdrain

aio_suspend   fsync     sem_post    tcflow 

alarm         getegid   setgid      tcflush

cfgetispeed   geteuid   setpgid     tcgetattr

cfgetospeed   getgid    setsid      tcgetgrp

cfsetispeed   getgroups setuid      tcsendbreak

cfsetospeed   getpgrp   sigaction   tcsetattr

chdir         getpid    sigaddset   tcsetpgrp

chmod         getppid   sigdelset   time

chown         getuid    sigemptyset timer_getoverrun

clock_gettime kill      sigfillset  timer_gettime

close         link      sigismember timer_settime

creat         lseek     signal      times

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже