Главная страница  Взаимодействие нетривиальных процессов 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 [ 49 ] 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

доступа для очереди. В листинге 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 может использоваться для идентификации сообщений, позволяя нескольким процессам мультиплексировать сообщения в одной очереди. Например, все сообщения от клиентов серверу имеют одно и то же значение типа.



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 [ 49 ] 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.