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

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

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, и считать разрешения



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.
Копирование материалов разрешено исключительно при условии цититирования.