Главная страница Взаимодействие нетривиальных процессов 11 len - atoi(argv[2]): 12 type = atoi(argv[3]): 13 mqid = Msgget(Ftok(argv[l]. 0), MSG W); 14 ptr = Calloc(sizeof(long) + len. sizeof(char)): 15 ptr->nitype = type: 16 MsgsndCmqid. ptr. len. 0); 17 exitCO): 18 } Программа msgrcv в листинге 6.4 приведен текст программы msgrcv, считывающей сообщение из очереди. В командной строке может быть указан параметр -п, отключающий блокировку, а параметр -t может быть использован для указания типа сообщения в функции msgrcv. 2 Не существует простого способа определить максимальный размер сообщения (об этом и других ограничениях мы поговорим в разделе 6.10), поэтому мы определим свою собственную константу. Листинг 6.4. Считывание сообщения из очереди System V svmsg/msgrcv.c 1 finclude unpipc.h 2 fdefine MAXMSG (8192 + sizeof(long)) 3 int 4 mainCint argc. char **argv) 6 int c. flag, mqid: 7 long type: 8 ssizej n: 9 struct msgbuf *buff: 10 type = flag - 0: 11 while ( (c = GetoptCargc. argv. nt: )) != -1) { 12 switch (c) { 13 case n: 14 flag 1= IPCJOWAIT: 15 break: 16 case t: 17 type = atoKoptarg): 18 break; 19 } 20 } 21 if (optind !- argc - 1) 22 err quit( usage: msgrcv [ -n ] [ -t type ] <pathname> ): 23 mqid - Msgget(Ftok(argv[optind], 0). MSG R): 24 buff = Malloc(MAXMSG): 25 n - Msgrcvcmqid, buff. MAXMSG. type, flag): продолжение Листинг 6.4 (продолжение) 26 printfCread d bytes, type - ld\n . n. buff->iTitype); 27 exit(O)-. 28 } Программа msgrmid Для удаления очереди сообщений мы вызываем функцию msgcti с командой IPC RMID, как показано в листинге 6.5. Листинг 6.5. Удаление очереди сообщений System V svmsg/msgrmid.c 1 #include unpipc.h 2 int 3 mainCint argc. char **argv) 5 int mqid: 6 if (argc !- 2) 7 err quit( usage: msgrmid <pathname> ): 8 mqid - Msgget(Ftok(argv[l]. 0). 0): 9 Msgcti(mqid. IPC RMID. NULL): 10 exit(O): 11 } Примеры Теперь воспользуемся четырьмя только что написанными программами. Создадим очередь и поместим в нее три сообщения: Solaris % msgcreate /tmp/no/such/file ftok error for pathname tmp/no/such/file and id 0: No such file or directory Solaris % touch /tmp/testl Solaris % msgcreate /tmp/testl Solaris % msgsnd /tmp/testl 1 100 Solaris % msgsnd /tmp/testl 2 200 Solaris % msgsnd /tmp/testl 3 300 Solaris % ipcs.-qo IPC status from <running system> as of Sat Jan 10 11:25:45 1998 T ID KEY MODE OWNER GROUP CBYTES ONUM Message Oueues: q 100 ОхООООПЗе --rw-r--r-- rstevens otherl 6 3 Сначала мы пытаемся создать очередь, используя имя несуществующего файла. Пример показывает, что файл, указываемый в качестве аргумента ftok, обязательно должен существовать. Затем мы создаем файл /tmp/testl и используем его имя при создании очереди сообщений. После этого в очередь помещаются три сообщения длиной 1, 2 и 3 байта со значениями типа 100, 200 и 300 (вспомните рис. 6.1). Программа ipcs показывает, что в очереди находятся 3 сообщения общим объемом 6 байт. Теперь продемонстрируем использование аргумента type при вызове msgrcv для считывания сообщений в произвольном порядке: Solaris % msgrcv -t 200 /tmp/testl read 2 bytes, type = 200 Solaris % msgrcv -t -300 /tmp/testl read 1 bytes, type = 100 Solaris % msgrcv /tmp/testl read 3 bytes, type = 300 Solaris % msgrcv -n /tmp/testl msgrcv error: No message of desired type В первом примере запрашивается сообщение с типом 200, во втором примере - сообщение с наименьшим значением типа, не превышающим 300, а в третьем - первое сообщение в очереди. Последний запуск msgrcv иллюстрирует действие флага IPCJOWAIT. Что произойдет, если мы укажем положительное значение типа, а сообщений с таким типом в очереди не обнаружится? Solaris % ipcs -qo IPC status from <running system> as of Sat Jan 10 11:37:01 1998 T ID KEY MODE OWNER GROUP CBYTES QNUM Message Queues: q 100 ОхООООПЗе --rw-r--r-- rstevens otherl 0 0 Solaris % msgsnd /tmp/testl 1 100 Solaris % msgrcv -t 999 /temp/testl *? нажали клавишу прерывания выполнения программы Solaris % msgrcv -n -t 999 /tmp/testl msgrcv error: No message of desired type Solaris % grep desired /usr/include/sys/errno.h #define ENOMSG 35 /* No message of desired type */ Solaris % msgrmid /tmp/testl Сначала мы вызываем i pes, чтобы убедиться, что очередь пуста, а затем помещаем в нее сообщение длиной 1 байт с типом 100. Затем мы запрашиваем сообщение с типом 999, и программа блокируется (при вызове msgrcv), ожидая помещения в очередь сообщения с указанным типом. Мы прерываем ожидание нажатием клавиши. Затем мы запускаем программу с флагом -п, предотвращающим блокировку, и видим, что в этом случае возвращается ошибка с кодом ENOMSG. После этого мы удаляем очередь с помощью программы msgrmid. Мы могли бы удалить очередь и с помощью системной команды Solaris % ipcrm -q 100 в которой указывается идентификатор очереди, или с помощью той же команды в другом формате Solaris % ipcrm -Q ОхИЗе где указывается ключ очереди сообщений. Программа msgrcvid Покажем теперь, что для получения доступа к очереди сообщений System V не обязательно вызывать msgget: все, что нужно, - это знать идентификатор очереди сообщений, который легко получить с помощью ipcs, и считать разрешения
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |