ПРИМЕЧАНИЕ
Поскольку n имеет тип size_t и мы не знаем, int это или long, мы преобразуем эту величину к типу long и используем строку формата %ld. В 64-разрядной реализации int будет 32-разрядным целым, a long и size_t будут 64-разрядными целыми.
Воспользуемся обеими программами, чтобы проиллюстрировать использование поля приоритета.
solaris % mqcreate /test1
solaris % mqgetattr /test1
max #msgs = 128, max #bytes/msg = 1024, #currently on queue = 0
solaris % mqsend /test1 100 99999
mq_send error: Invalid argument
solaris % mqsend /test1 100 6
solaris % mqsend /test1 50 18
solaris % mqsend /test1 33 18
solaris % mqreceive /test1
read 50 bytes, priority = 18
solaris % mqreceive /test1
read 33 bytes, priority = 18
Solaris % mqreceive /test1
read 100 bytes, priority = 6
Solaris % mqreceive –n /test1
mq_receive error: Resource temporarily unavailable
Мы видим, что mq_receive действительно возвращает старейшее сообщение с наивысшим приоритетом.
5.5. Ограничения очередей сообщений
Мы уже сталкивались с двумя ограничениями, устанавливаемыми для любой очереди в момент ее создания:
■ mq_maxmsg — максимальное количество сообщений в очереди;
■ mq_msgsize — максимальный размер сообщения.
Не существует каких-либо ограничений на эти значения, хотя в рассматриваемых реализациях необходимо наличие в файловой системе места для файла требуемого размера. Кроме того, ограничения на эти величины могут накладываться реализацией виртуальной памяти (см. упражнение 5.5).
Другие два ограничения определяются реализацией:
■ MQ_OPEN_MAX — максимальное количество очередей сообщений, которые могут быть одновременно открыты каким-либо процессом (Posix требует, чтобы эта величина была не меньше 8);
■ MQ_PRIO_MAX — максимальное значение приоритета плюс один (Posix требует, чтобы эта величина была не меньше 32).
Эти две константы часто определяются в заголовочном файле
Пример: программа 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), процесс не будет заблокирован, но нам придется регулярно вызывать эту функцию, чтобы получить сообщение, когда оно будет отправлено. Мы уже говорили, что такая процедура называется