Главная страница Взаимодействие нетривиальных процессов Листинг 6.13 (продолжение) 42 Mesg sencl(writefd. &niesg): 43 } 44 } Листинг 6.14. Функция main клиента svmsgmpxlq/cl ient niai n ,с 1 #include svmsg.h 2 void clientCint. int); 3 int 4 mainCint argc. char **argv) 6 int msqid: 7 /* сервер должен был создать очередь */ 8 msqid = MsggetCMQ KEY1, 0): 9 clientCmsqid. msqid): /* одна очередь в обе стороны */ 10 exitCO): Листинг 6.15. Функция client svmsgmpxlq/client.с 1 #include mesg.h 2 void 3 ClientCint readfd. int writefd) 5 size t len; 6 ssize t n; 7 char *ptr: 8 struct mymesg mesg; 9 /* инициализируем буфер идентификатором процесса и пробелом */ 10 snprintfCmesg.mesg data, MAXMESGDATA, Id , Clong) getpidO): 11 len = strlen(mesg.mesg data); 12 ptr = mesg.mesg data + len; 13 /* считываем полное имя фа11ла */ 14 FgetsCptr. MAXMESGDATA - len, stdin); 15 len = strlenCmesg.mesg data); 16 if Cmesg.mesg data[len-1] == Vn) 17 len--; /* удаляем перевод строки fgetsC) */ 18 mesg.mesg len = len; 19 mesg.mesg type = 1; 20 /* записываем PID и имя фа11ла в канал IPC */ 21 Mesg sendCwritefd. &mesg); 22 /* считываем из канала IPC, записываем в stdout */ 23 mesg, mesg type = getpidO; 24 wliile С Cn = Mesg recv С readfd. &mesg)) > 0) 25 WriteCSTDOUTJILENO, mesg.mesg data, n); 26 } Пример: одна очередь для каждого клиента Изменим теперь предыдущий пример таким образом, чтобы все запросы клиентов передавались по одной очереди, но для отправки ответов использовалась бы отдельная очередь для каждого клиента. На рис. 6.3 изображена схема такого приложения. дочерний процесс родительский процесс дочерний процесс клиент 1 клиент 2 Рис. 6.3. Одна очередь для сервера и по одной для каждого клиента Ключ очереди сервера должен быть известен клиентам, а сами клиенты создают свои очереди с ключом IPC PRIVATE. Вместо передачи серверу идентификатора процесса клиенты сообщают ему идентификатор своей очереди, в которую сервер направляет свой ответ. Этот сервер является параллельным: для каждого нового клиента порождается отдельный процесс. ПРИМЕЧАНИЕ - При такой схеме может возникнуть проблема в случае гибели клиента, потому что тогда сообщения останутся в его очереди навсегда (по крайней мере до перезагрузки ядра или явного удаления очереди другим процессом). Нижеследующие заголовочные файлы и функции не претерпевают изменений по сравнению с предыдущими версиями: ж mesg.h (листинг4.12); ш svmsg, h (листинг 6.7); Ш функция maiп сервера (листинг 6,12); ш функция mesg send (листинг 4.13). Функция main клиента приведена в листинге 6.16; она слегка изменилась по сравнению с листингом 6.14. Мы открываем очередь сервера с известным ключом (MQ KEY1) и создаем нашу собственную очередь с ключом IPC PRI VATE. Два идеи- тификатора этих очередей становятся аргументами функции с1 i ent (листинг 6.17). После завершения работы клиента его персональная очередь удаляется. Листинг 6.16. Функция main клиента svmsgmpxnq/cl i ent niai n. с 1 finclude svmsg.h 2 void clientCint. int); 3 int 4 mainCint argc. char **argv) 6 int readid. writeid; 7 /* сервер должен создать свою очередь */ 8 writeid = MsggetСMQ KEY1. 0); 9 /* мы создаем свою собственную очередь */ 10 readid = MsggetClPC PRIVATE, SVMSG MODE IPC CREAT); 11 client Сreadid. writeid); 12 /* и удаляем нашу собственную очередь */ 13 MsgctiCreadid, IPC RMID. NULL); 14 exitCO); 15 } Листинг 6.17. Функция client svmsgmpxnq/client.c 1 #include mesg.h 2 void 3 clientCint readid. int writeid) 5 size t len; 6 ssize t n; 7 char *ptr; 8 struct mymesg mesg; 9 /* инициализируем буфер идентификатором очереди и пробелом */ 10 snprintfCmesg.mesg data. MAXMESGDATA. %й . readid); 11 len = strlenCmesg.mesg data); 12 ptr = mesg.mesg data + len; 13 /* считываем имя фа11ла */ 14 FgetsCptr. MAXMESGDATA - len. stdin); 15 len = strlenCmesg.mesg data); 16 if cmesg.mesg data[len-l] == \n) 17 len--; /* удаляем перевод строки fgetsC) */ 18 mesg. mesgjen = len; 19 mesg. mesg Jype = 1; 20 /* отправляем идентификатор очереди и имя фа11ла серверу */ 21 MesgjendCwriteid, &mesg); 22 /* считываем ответ из наше11 очереди и записываем его в stdout */
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |