Главная страница Взаимодействие нетривиальных процессов доступа для очереди. В листинге 6.6 приведен упрощенный вариант программы msgrcv из листинга 6.4. Здесь мы уже не используем msgget. Вместо этого используется идентификатор очереди сообщений, являющийся обязательным аргументом командной строки. Листинг 6.6. Считывание из очереди сообщений System V с известным идентификатором svmsg/msgrcvid.c 1 #inc1ude unpipc.h 2 #define MAXMSG (8192 + sizeof(long)) 3 int 4 niain(int argc, char **argv) 6 int mqid; 7 ssize t n; 8 struct msgbuf *buff; 9 if (argc ]= 2) 10 err quit( usage: msgrcvid <mqid> ): 11 mqid = atoi(argv[l]); 12 buff - Mailoc(MAXMSG); 13 n = Msgrcv(mqid, buff, MAXMSG, 0, 0); 14 printf( read d bytes, type = ld\n , n, buff->mtype); 15 exit(O); 16 } Вот пример использования этой программы: Solaris % touch /tmp/testid Solaris % msgcreate /tmp/testid Solaris % msgsnd /tmp/test1d 4 400 Solaris % ipcs -qo IPC status from <running system> as of Wed Mar 25 09:48:28 1998 T ID KEY MODE OWNER GROUP CBYTES ONUM Message Oueues: q 150 0x0000118a --rw-r--r-- rstevens otherl 4 1 Solaris % msgrcvid 150 read 4 bytes, type = 400 Идентификатор очереди (150) мы узнали с помощью i pes, его мы и предоставляем программе msgrcvi d в качестве аргумента командной строки. Этот же метод можно использовать для семафоров System V (упражнение 11.1) и разделяемой памяти System V (упражнение 14.1). 6.7. Пример программы клиент-сервер Перепишем наш пример программы типа клиент-сервер из раздела 4.2 с использованием двух очередей сообщений. Одна из очередей предназначена для передачи сообщений от клиента серверу, а другая - в обратную сторону. Заголовочный файл s vmsg, h приведен в листинге 6.7. Мы подключаем наш стандартный заголовочный файл и определяем ключи для каждой из очередей сообщений. Листинг 6.7. Заголовочный файл svmsg.h для программы клиент-сервер, использующей очереди сообщений svmsgcliserv/svmsg.h 1 finclude unpipc.h 2 #define MQ KEY1 1234L 3 #define MQ KEY2 2345L Функция mai n для сервера приведена в листинге 6.8. Программа создает обе очереди сообщений, и не беда, если какая-нибудь из них уже существует, потому что мы не указываем флаг IPC EXCL. Функция server дана в листинге 4.16. Она вызывает наши собственные функции mesg send и mesg recv, новые версии которых будут приведены ниже. Листинг 6.8. Функция main программы-сервера, использующей очереди сообщений svmsgcl i serv/server niai n. с 1 #include svmsg.h 2 void serverCint. int); 3 int 4 mainCint argc, char **argv) 6 int readid, writeid; 7 readid = MsggetСMQ KEY1. SVMSG MODE IPC CREAT): 8 writeid - MsggetCMQ KEY2, SVMSG MODE IPC CREAT); 9 serverCreadid. writeid); 10 exitCO): 11 } Листинг 6.9. Функция main программы-клиента, использующей очереди сообщений svmsgcliserv/client main.c 1 #include svmsg.h 2 void clientCint. int): 3 int 4 mainCint argc. char **argv) 6 int readid. writeid; 7 /* assumes server has created the queues */ 8 writeid = MsggetСMQ KEY1. 0): 9 readid = MsggetCMQ KEY2, 0); 10 clientСreadid. writeid): 11 /* now we can delete the queues */ Листинг 6.9 (продолжение) 12 MsgctKreadid, IPC RMID. NULL): 13 Msgcti(writeid. IPC RMID. NULL): 14 exit(O): 15 } В листинге 6.9 приведен текст функции main программы-клиента. Программа открывает две очереди сообщений и вызывает функцию с1 ient из листинга 4.15. Эта функция использует две другие: mesg send и mesg recv, которые будут приведены ниже. И функция с1 ient, и функция server используют формат сообщений, изображенный в листинге 4.12. Для передачи и приема сообщений они используют функции mesg send и mesg recv. Старые версии этих функций, приведенные в листингах 4.13 и 4.14, вызывали write и read и работали с програмхшыми каналами и FIFO, так что нам придется переписать их для использования очередей сообщений, в листингах 6.10 и 6.11 приведены новые версии этих функций. Обратите внимание, что аргументы функций не изменились, поскольку первый целочисленный аргумент может содержать как целочисленный дескриптор программного канала или FIFO, так и целочисленный дескриптор очереди сообщений. Листинг 6.10. Функция mesg send, работающая с очередью сообщений System V svnisgcliserv/niesg send.c 1 #include mesg.h 2 ssize t 3 mesg send(int id, struct mymesg *mptr) 5 return(msgsnd(id, &(mptr->mesg type), mptr->mesgjen, 0)): Листинг 6.11. Функция mesg recv, работающая с очередью сообщений System V svmsgcli serv/mesg recv.с 1 #include mesg.h 2 ssizej 3 mesg recv(int id, struct mymesg *mptr) 5 ssizej n: 6 n = msgrcv(id, &(mptr->mesg type), MAXMESGDATA, mptr->mesg type, 0): 7 mptr->mesgjen = n; /* количество возвращаемых данных */ 8 return(n); /* -1 в случае ошибки, О - конец файла, иначе - >0 */ 6.8. Мультиплексирование сообщений Наличие поля type у каждого сообщения в очереди предоставляет две интересные возможности: 1. Поле type может использоваться для идентификации сообщений, позволяя нескольким процессам мультиплексировать сообщения в одной очереди. Например, все сообщения от клиентов серверу имеют одно и то же значение типа.
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |