Функция 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.
Сигналы Posix: функции типа Async-Signal-Safe
Недостаток пpoгрaммы из листинга 5.8 в том, что она вызывает mq_notify, mq_receive и printf из обработчика сигнала. Ни одну из этих функций вызывать оттуда не следует.
Функции, которые могут быть вызваны из обработчика сигнала, относятся к группе, называемой, согласно Posix,
Функции, которых нет в этом списке, не должны вызываться из обработчика сигнала. Обратите внимание, что в списке отсутствуют стандартные функции библиотеки ввода-вывода и функции 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
dup mkdir sigpause umask
dup2 mkfifo sigpending uname
execle open sigprocmask unlink
execve pathconf sigqueue utime
_exit pause sigset wait