■ MQ_OPEN_MAX — максимальное количество очередей сообщений, которые могут быть одновременно открыты каким-либо процессом (Posix требует, чтобы эта величина была не меньше 8);
■ MQ_PRIO_MAX — максимальное значение приоритета плюс один (Posix требует, чтобы эта величина была не меньше 32).
Эти две константы часто определяются в заголовочном файле unistd.h и могут быть получены во время выполнения программы вызовом функции sysconf, как мы покажем далее.
Пример: программа mqsysconf
Программа в листинге 5.7 вызывает функцию sysconf и выводит два ограничения на очереди сообщений, определяемые реализацией.
//pxmsg/mqsysconf.с
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 printf("MQ_OPEN_MAX = %ld, MQ_PRIO_MAX = %ld\n",
6 Sysconf(_SC_MQ_OPEN_MAX), Sysconf(_SC_MQ_PRIO_MAX));
7 exit(0);
8 }
Запустив эту программу в наших двух операционных системах, получим:
solaris % mqsysconf
MQ_OPEN_MAX = 32, MQ_PRIO_MAX = 32
alpha % mqsysconf
MQ_OPEN_MAX = 64, MQ_PRIO_MAX = 256
5.6. Функция mq_notify
Один из недостатков очередей сообщений System V, как мы увидим в главе 6, заключается в невозможности уведомить процесс о том, что в очередь было помещено сообщение. Мы можем заблокировать процесс при вызове msgrcv, но тогда мы не сможем выполнять другие действия во время ожидания сообщения. Если мы укажем флаг отключения блокировки при вызове msgrcv (IPC_NOWAIT), процесс не будет заблокирован, но нам придется регулярно вызывать эту функцию, чтобы получить сообщение, когда оно будет отправлено. Мы уже говорили, что такая процедура называется
ПРИМЕЧАНИЕ
В этом и всех последующих разделах данной главы обсуждаются более сложные вопросы, которые могут быть пропущены при первом чтении.
Очереди сообщений Posix допускают асинхронное уведомление о событии, когда сообщение помещается в очередь. Это уведомление может быть реализовано либо отправкой сигнала, либо созданием программного потока для выполнения указанной функции.
Мы включаем режим уведомления с помощью функции mq_notify:
#include mqueue.h
int mq_notify(mqd_t
Эта функция включает и выключает асинхронное уведомление о событии для указанной очереди. Структура sigevent впервые появилась в стандарте Posix.1 для сигналов реального времени, о которых более подробно рассказано в следующем разделе. Эта структура и все новые константы, относящиеся к сигналам, определены в заголовочном файле signal.h:
union sigval {
int sival_int; /* целое значение */
void *sival_ptr; /* указатель */
};
struct sigevent {
int sigev_notify; /* SIGEV_{NONE,SIGNAL,THREAD} */
int sigev_signo; /* номер сигнала, если SIGEV_SIGNAL */
union sigval sigev_value; /* передается обработчику сигнала или потоку */
/* Следующие два поля определены для SIGEV_THREAD */
void (*sigev_notify_function) (union sigval);
pthread_attr_t *sigev_notify_attributes;
Мы вскоре приведем несколько примеров различных вариантов использования уведомления, но о правилах, действующих для этой функции всегда, можно упомянуть уже сейчас.
1. Если аргумент
2. Если аргумент
3. Только один процесс может быть зарегистрирован на уведомление для любой данной очереди в любой момент.