15 Mq_send(mqd, ptr, len, prio);
16 exit(0);
17 }
И размер сообщения, и его приоритет являются обязательными аргументами командной строки. Буфер под сообщение выделяется функцией callос, которая инициализирует его нулем.
Пример: программа mqreceive
Программа в листинге 5.6 считывает сообщение из очереди.
//pxmsg/mqreceive.с
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int с flags;
6 mqd_t mqd;
7 ssize_t n;
8 uint_t prio;
9 void *buff;
10 struct mq_attr attr;
11 flags = O_RDONLY;
12 while ((c = Getopt(argc, argv, "n")) != –1) {
13 switch (c) {
14 case 'n':
15 flags |= O_NONBLOCK;
16 break;
17 }
18 }
19 if (optind != argc – 1)
20 err_quit("usage: mqreceive [ –n ] name");
21 mqd = Mq_open(argv[optind], flags);
22 Mq_getattr(mqd, attr);
23 buff = Malloc(attr.mqjnsgsize);
24 n = Mq_receive(raqd, buff, attr.mq_msgsize, prio);
25 printf("read %ld bytes, priority = %u\n", (long) n, prio);
26 exit(0);
27 }
14-17 Параметр командной строки –n отключает блокировку. При этом программа возвращает сообщение об ошибке, если в очереди нет сообщений.
21-25 Мы открываем очередь и получаем ее атрибуты, вызвав mq_getattr. Нам обязательно нужно определить максимальный размер сообщения, потому что мы должны выделить буфер подходящего размера, чтобы вызвать mq_receive. Программа выводит размер считываемого сообщения и его приоритет.
ПРИМЕЧАНИЕ
Поскольку 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).
Другие два ограничения определяются реализацией: