Чтение онлайн

на главную - закладки

Жанры

UNIX: взаимодействие процессов

Стивенс Уильям Ричард

Шрифт:

Очередям сообщений Posix и System V не хватает полезной функции: получатель не может определить отправителя сообщения. Эта информация могла бы пригодиться многим приложениям. К сожалению, большинство механизмов передачи сообщений IPC не позволяют определить отправителя сообщений. В разделе 15.5 мы расскажем, как эта возможность обеспечивается для дверей. В разделе 14.8 [24] описано, как эта возможность обеспечивается в BSD/OS для доменных сокетов Unix. В разделе 15.3.1 [21] описано, как SVR4 передает информацию об отправителе по каналу при передаче по нему дескриптора. В настоящее время методы BSD/OS широко используются, и хотя реализация SVR4 является частью стандарта Unix 98, она требует передачи дескриптора по каналу, что обычно является более дорогостоящей операцией, чем просто передача данных. Мы не можем предоставить отправителю возможность передать информацию о себе (например, эффективный идентификатор пользователя) в самом сообщении, поскольку мы не можем быть уверены, что эта информация окажется истинной. Хотя разрешения доступа к очереди сообщений определяют, имеет ли право отправитель помещать в нее сообщения, это все равно не дает однозначности. Существует возможность создавать одну очередь для каждого отправителя (о которой рассказывается в связи с очередями System V в разделе 6.8), но это плохо подходит для больших приложений. Наконец, если функции для работы с очередями сообщений реализованы как пользовательские функции (как мы показываем в разделе 5.8), а не как часть ядра, мы не можем доверять никакой информации об отправителе, передаваемой с сообщением, так как ее легко подделать. 

Пример: программа mqsend

В листинге 5.5 приведен текст программы, помещающей сообщение в очередь.

Листинг 5.5. Программа mqsend

//pxmsg/mqsend.c

1 #include "unpipc.h"

2 int

3 main(int argc, char **argv)

4 {

5 mqd_t mqd;

6 void *ptr;

7 size_t len;

8 uint_t prio;

9 if (argc != 4)

10 err_quit("usage: mqsend <name> <#bytes> <priority>");

11 len = atoi(argv[2]);

12 prio = atoi(argv[3]);

13 mqd = Mq_open(argv[1], O_WRONLY);

14 ptr = Calloc(len, sizeof (char));

15 Mq_send(mqd, ptr, len, prio);

16 exit(0);

17 }

И размер сообщения, и его приоритет являются обязательными аргументами командной строки. Буфер под сообщение выделяется функцией callос, которая инициализирует его нулем.

Пример: программа mqreceive

Программа в листинге 5.6 считывает сообщение из очереди.

Листинг 5.6. Программа mqreceive

//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 }

Параметр -n запрещает блокировку

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 100 байт, приоритет 6

solaris % mqsend /test1 50 18 50 байт, приоритет 18

solaris % mqsend /test1 33 18 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 действительно возвращает старейшее сообщение с наивысшим приоритетом. 

Поделиться:
Популярные книги

На гребне обстоятельств

Шелег Дмитрий Витальевич
7. Живой лед
Фантастика:
фэнтези
5.25
рейтинг книги
На гребне обстоятельств

Путь Князя. Возрождение. Часть 2

Рокотов Алексей
7. Путь князя
Фантастика:
фэнтези
рпг
5.00
рейтинг книги
Путь Князя. Возрождение. Часть 2

Темная сторона. Том 1

Лисина Александра
9. Гибрид
Фантастика:
технофэнтези
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Темная сторона. Том 1

Забытые боги

Рокотов Алексей
4. Путь князя
Фантастика:
фэнтези
рпг
попаданцы
5.00
рейтинг книги
Забытые боги

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Иной. Том 1. Школа на краю пустыни

Amazerak
1. Иной в голове
Фантастика:
боевая фантастика
рпг
аниме
5.75
рейтинг книги
Иной. Том 1. Школа на краю пустыни

Измена. Свадьба дракона

Белова Екатерина
Любовные романы:
любовно-фантастические романы
эро литература
5.00
рейтинг книги
Измена. Свадьба дракона

Пламенев. Книга VIII

Карелин Сергей Витальевич
8. Пламенев
Фантастика:
аниме
уся
сказочная фантастика
фэнтези
фантастика: прочее
5.00
рейтинг книги
Пламенев. Книга VIII

Ермак. Регент

Валериев Игорь
10. Ермак
Фантастика:
попаданцы
альтернативная история
4.75
рейтинг книги
Ермак. Регент

Наша навсегда

Зайцева Мария
2. Наша
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Наша навсегда

Я все еще не князь. Книга XV

Дрейк Сириус
15. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я все еще не князь. Книга XV

Развод в 45. От любви до ненависти

Гофман Крис
6. Развод
Любовные романы:
остросюжетные любовные романы
5.40
рейтинг книги
Развод в 45. От любви до ненависти

Инженерный Парадокс 9

Cyberdawn
9. Инженерный Парадокс
Фантастика:
боевая фантастика
юмористическое фэнтези
попаданцы
5.00
рейтинг книги
Инженерный Парадокс 9

Диверсант

Вайс Александр
2. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Диверсант