Читать «UNIX: взаимодействие процессов» онлайн - страница 79
Уильям Ричард Стивенс
Структура sigaction претерпела изменения с добавлением поддержки сигна-5-7 лов реального времени: к ней было добавлено новое поле sa_sigaction:
struct sigaction {
void (*sa_handler)(); /* SIG_DFL, SIG_IGN или адрес обработчика сигнала */
sigset_t sa_mask; /* дополнительные блокируемые сигналы */
int sa_flags; /* параметры сигналов: SA_XXX */
void (*sa_sigaction)(int, siginfo_t, void *);
};
Правила действуют следующие:
■ Если в поле sa_flags установлен флаг SA_SIGINFO, поле sa_sigaction указывает адрес функции-обработчика сигнала.
■ Если флаг SA_SIGINFO не установлен, поле sa_handler указывает адрес функции-обработчика сигнала.
■ Чтобы сопоставить сигналу действие по умолчанию или игнорировать его, следует установить sa_handler равным либо SIG_DFL, либо SIG_IGN и не устанавливать флаг SA_SIGINFO.
Установка SA_SIGINFO
8-17 Мы всегда устанавливаем флаг SA_SIGINFO и указываем флаг SA_RESTART, если перехвачен какой-либо другой сигнал, кроме SIGALRM.
5.8. Реализация с использованием отображения в память
Теперь рассмотрим реализацию очередей сообщений Posix с использованием отображения в память, взаимных исключений и условных переменных Posix.
ПРИМЕЧАНИЕ
Взаимные исключения и условные переменные описаны в главе 7, а ввод-вывод с отображением в память — в главах 12 и 13. Вы можете отложить данный раздел до ознакомления с этими главами.
На рис. 5.2 приведена схема структур данных, которыми мы пользуемся для реализации очереди сообщений Posix. Изображенная очередь может содержать до четырех сообщений по 7 байт каждое.
В листинге 5.16 приведен заголовочный файл mqueue.h, определяющий основные структуры, используемые в этой реализации.
Тип mqd_t
Дескриптор нашей очереди сообщений является просто указателем на структуру mq_infо. Каждый вызов mq_open выделяет память под одну такую структуру, а вызвавшему возвращается указатель на нее. Повторим, что дескриптор очереди сообщений не обязательно является небольшим целым числом, как дескриптор файла — единственное ограничение, накладываемое Posix, заключается в том, что этот тип данных не может быть массивом.
Листинг 5.16. Заголовочный файл mqueue.h
//my_pxmsg_mmap/mqueue.h
1 typedef struct mymq_info *mymqd_t;
2 struct mymq_attr {
3 long mq_flags; /* флаг очереди : O_NONBLOCK */
4 long mq_maxmsg; /* максимальное количество сообщений в очереди */
5 long mq_msgsize; /* максимальный размер сообщения в байтах */
6 long mq_curmsgs; /* количество сообщений в очереди */
7 };
8 /* одна структура mymq_hdr{} на очередь, в начале отображаемого файла */
9 struct mymq_hdr {
10 struct mymq_attr mqh_attr; /* атрибуты очереди */
11 long mqh_head; /* индекс первого сообщения*/
12 long mqh_free; /* индекс первого пустого сообщения */
13 long mqh_nwait; /* количество заблокированных mq_receive() потоков */
14 pid_t mqh_pid; /* ненулевой PID. если включено уведомление */
15 struct sigevent mqh_event; /* для mq_notify() */
16 pthread_mutex_t mqh_lock; /* блокировка: mutex*/
17 pthread_cond_t mqh_wait; /* и условная переменная */