Главная страница Взаимодействие нетривиальных процессов тогда как сообщения сервера клиентам имеют различные значения типов, уникальные для каждого клиента. Естественно, в качестве значения типа сообщения, гарантированно уникального для каждого клиента, можно использовать идентификатор процесса клиента. 2. Поле type может использоваться для установки приоритета сообщений. Это позволяет получателю считывать сообщения в порядке, отличном от обычного для очередей (FIFO). В программных каналах и FIFO данные могли приниматься только в том порядке, в котором они были отправлены. Очереди System V позволяют считывать сообщения в произвольном порядке в зависимости от значений типа сообщений. Более того, можно вызывать msgrcv с флагом IPC NOWAIT для считывания сообщений с конкретным типом и немедленного возвращения управления процессу в случае отсутствия таких сообщений. Пример: одна очередь на приложение Вспомните наш простой пример с одним процессом-сервером и одним процессом-клиентом. Если применять программные каналы или FIFO, необходимо наличие двух каналов IPC для передачи данных в обоих направлениях, поскольку эти типы IPC являются однонаправленными. Очереди сообщений позволяют передавать данные в обоих направлениях, причем поле type может использоваться для указания адресата (клиента или сервера). Рассмотрим усложненный вариант: один сервер и несколько клиентов. В этом случае можно использовать значение типа 1, например, для обозначения сообщений от любого клиента серверу. Если клиент передаст серверу свой идентификатор процесса в качестве части сообщения, сервер сможет отсылать клиенту сообщения, используя его идентификатор в качестве значения типа сообщения. Каждый клиент будет использовать свой PID в качестве аргумента type при вызове msgrcv. На рис. 6.2 приведен пример использования очереди для мультиплексирования этих сообщений между несколькими клиентами и одним сервером. сервер type = 1234 or 9876: ответы сервера type = 1: запросы клиентов очередь известный ключ клиент 1
PID 1234 Рис. 6.2. Мультиплексирование сообщений между несколькими клиентами и одним сервером ПРИМЕЧАНИЕ- При использовании одного канала IPC одновременно клиентами и сервером всегда существует потенциальная возможность зависания (deadlock). Клиенты могут (в этом примере) заполнить очередь своими сообщениями, не давая серверу возможности отправить ответ. В этому случае клиенты заблокируются при вызове msgsnd, как и сервер. Одно из соглашений, исключающих возможность такой взаимной блокировки, заключается в том, что сервер должен всегда отключать блокировку записи в очередь сообщений. Теперь мы можем переделать наш пример с клиентом и сервером, используя одну очередь сообщений с различными типами для разных адресатов. Эти программы используют следующее соглашение: сообщения с типом 1 адресованы серверу, а все остальные сообщения имеют тип, соответствующий идентификатору процесса адресата. При этом запрос клиента должен содержать его PID вместе с полным именем запрашиваемого файла, аналогично программе в разделе 4.8. В листинге 6.12 приведен текст функции main сервера. Заголовочный файл svmsg. h был приведен в листинге 6.7. Создается единственная очередь сообщений (если она существует, ошибки не возникнет). Идентификатор этой очереди сообщений используется в качестве обоих аргументов при вызове функции server. Листинг 6.12. Функция main сервера svnisgnipxlq/server niain.c 1 #inclucle svmsg.h 2 void serverCint, int); 3 int 4 mainCint argc. char **argv) 6 int msqid; 7 msqid - MsggetСMQ KEY1. SVMSG MODE IPC CREAT): 8 serverCmsqid. msqid); /* одна очередь в обе стороны */ 9 exitCO); 10 } Функция server обеспечивает работу сервера. Ее текст приведен в листинге 6.13. Эта функция представляет собой комбинацию листинга 4.10 - нашего сервера FIFO, считывавшего команды, состоявшие из идентификатора процесса и полного имени файла, - и листинга 4.16, в котором использовались функции mesg send и mesg recv. Обратите внимание, что идентификатор процесса, отправляемый клиентом, используется в качестве типа для всех сообщений, отправляемых сервером этому клиенту. Эта функция представляет собой бесконечный цикл, в котором считываются запросы клиентов и отсылаются запрошенные файлы. Этот сервер является последовательным (см. раздел 4.9). в листинге 6.14 приведен текст функции mai п клиента. Клиент открывает очередь сообщений, которая должна была быть создана сервером заранее. Функция client, текст которой дан в листинге6.15, обеспечивает всю обработку со стороны клиента. Эта функция представляет собой комбинацию про- грамм из листингов 4.11 и 4.15. В первой программе клиент отсылал свой идентификатор и полное имя файла, а во второй программе использовались функции mesg send и mesg recv. Обратите внимание, что тип сообщений, запрашиваемых функцией mesg recv, совпадает с идентификатором процесса клиента. Функции с1 lent и server используют функции mesg send и mesg recv из листингов 6.9 и 6.11. Листинг 6.13. Функция server svmsgmpxlq/server.c 1 finclude mesg.h 2 void 3 serverCint readfd. int writefd) 5 FILE *fp; 6 char *ptr; 7 pid t pid; 8 ssize t n; 9 struct mymesg mesg; 10 for С : : ) { 11 /* считывание полного имени из канала IPC */ 12 mesg.mesg type = 1: 13 if С Cn - Mesg recvCreadfd. &mesg)) == 0) { 14 err msgС pathname missing ); 15 continue; 16 } 17 mesg.mesg data[n] = \0; /* полное имя */ 18 if С Cptr = strchrCmesg.mesg data, )) == NULL) { 19 err msgC bogus request: s . mesg.mesg data); 20 continue: 21 } 22 *ptr++ =0: /* ptr = полное имя */ 23 pid = atolCmesg.mesg data): 24 mesg.mesg type = pid: /* для обратных сообщений */ 25 if С Cfp = fopenCptr. г )) == NULL) { 26 /* 4еггог: must tell client */ 27 snprintfCmesg.mesg data + n. sizeofCmesg.mesg data) - n. 28 ; cant open, s\n , strerrorCerrno)): 29 mesg, mesgjen = strlenCptr): 30 memmoveCmesg,mesg data. ptr. mesg.mesgjen); 31 Mesg sendCwritefd. &mesg): 32 } else { 33 /* файл открыт, копируем клиенту */ 34 while CFgetsCmesg,mesg data, MAXMESGDATA, fp) != NULL) { 35 mesg,mesgjen = strlenCmesg,mesg data); 36 Mesg sendСwritefd, &mesg); 37 } 38 FcloseCfp): 39 } 40 /* сообщение нулевой длины заканчивает связь */ 41 mesg.mesgjen = 0: продолжение
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |