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

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

канал и при считывании из канала родительским процессом. Для ускорения обработки порожденный процесс может создать сегмент совместно используемой с породившим процессом памяти, а канал использовать как флаг (упражнение 12.5).

ПРИМЕЧАНИЕ -

В листинге 5.12 мы привели решение с использованием очередей сообщений Posix, которое не требовало вызова fork, Для очередей сообщений Posix можно было обойтись одним процессом, поскольку они предусматривают уведомление о появлении нового сообщения с помощью сигнала. Для очередей System V такая возможность не предусмотрена, поэтому приходится порождать процесс, который будет блокироваться при вызове msgrcv.

Другим недостатком очередей сообщений System V по сравнению с сетевым интерфейсом является невозможность считывания сообщений из оперативной памяти (возможность, предоставляемая флагом MSG PEEK для функций recv, recvf rom, recvmsg [24, с. 356]). Если бы такая возможность имелась, в предложенной только что схеме клиент-сервер (для обхода проблемы с sel ect) можно было бы сделать работу более эффективной, указав флаг реек при вызове msgrcv дочерним процессом и записав 1 байт в канал при приходе сообщения, а родительский процесс тогда просто считывал бы сообщение из очереди.

6.10. Ограничения, накладываемые на очереди сообщений

Как отмечалось в разделе 3.8, на очереди сообщений часто накладываются системные ограничения. В табл. 6.2 приведены значения этих ограничений для двух конкретных реализаций. Первая колонка представляет собой традиционное имя System V для переменной ядра, хранящей это ограничение.

Таблица 6.2. Характерные значения ограничений для очередей сообщений

Описание

DUnix4.0B

Solaris 2.6

msgmax

Максимальное количество байтов в сообщении

8192

2048

msgmnb

Максимальное количество байтов в очереди сообщений

16 384

4096

msgmni

Максимальное количество очередей сообщений

в системе

msgtlq

Максимальное количество сообщений в системе

Bo многих реализациях, производных от SVR4, имеются дополнительные ограничения, унаследованные от первоначальной реализации: размер сегмента для хранения данных сообщений msgssz часто имеет значение 8. Сообщение с 21 байтом данных будет храниться в трех сегментах, причем последние 3 байта последнего сегмента не будут использованы. Другая переменная, msgseg, определяет количество выделенных сегментов; часто она имеет значение 1024. Исторически это значение хранится в коротком целом и, следовательно, не должно превышать 32 768. Таким образом, для всех сообщений в системе отводится объем, представляющий собой произведение этих двух величин, то есть 8x1024.



В этом разделе мы хотели показать типичные значения ограничений, чтобы помочь в планировании переносимых программ. При выполнении приложений, активно использующих очереди сообщений, обычно требуется настройка этих (или аналогичных) параметров ядра (что описано в разделе 3.8).

Пример

в листинге 6.21 приведен текст программы, которая определяет четыре ограничения, показанные в табл. 6.2.

Листинг 6.21. Определение системных ограничений для очередей сообщений System V

svmsg/limits.c

1 #-inclucle unpipc.h

2 Idefine MAXJATA 64*1024

3 Idefine MAX NMESG 4096

4 #clefine MAX NIDS 4096

5 int niax niesg;

6 struct mymesg {

7 long type;

8 char dataEMAXJATA];

9 } mesg;

10 int

11 mainCint argc, char **argv)

12 {

13 int i. j, msqid. qid[MAX NIDS];

14 /* определение максимального размера сообщения */

15 msqid = Msgget(IPC PRIVATE. SVMSG MODE IPC CREAT);

16 mesg.type = 1;

17 for (i - MAXJATA; i > 0; i -= 128) {

18 if (msgsndCmsqid. &mesg. i. 0) == 0) {

19 printf( maximum amount of data per message = d\n . i);

20 max mesg = i;

21 break;

22 }

23 if (errno != EINVAL)

24 err sys( msgsnd error for length Xd . i);

25 }

26 if (i == 0)

27 err quit( i == 0 );

28 MsgctKmsqid. IPCJMID, NULL):

29 /* количество сообщений в очереди */

30 mesg.type =1:

31 for (i = 8; i <= max mesg; i *= 2) {

32 msqid - Msgget (I PCJR! VATE, SVMSG MODE IPCJREAT):

33 for (j - 0; j < MAXJMESG; j++) {

34 if (msgsnd(msqid. &mesg, i. IPCJOWAIT) != 0) {

35 if (errno == EAGAIN)

36 break;

37 err sys( msgsnd error, i = d. j = d . 1. j): л

продолжение -В/



Листинг 6.21 (продолжение)

38 break;

39 }

40 }

41 printfCd d-byte messages were placed onto queue. , j. i):

42 printfC d bytes total\n . i*j);

43 Msgcti(msqid. IPC RMID. NULL);

44 }

45 /* максимальное количество идентификаторов */

46 mesg.type = 1;

47 for (i = 0; i <- MAX NIDS: i++) {

48 if ( (qid[i] - msgget(IPC PRIVATE. SVMSG MODE IPC CREAT)) == -1) {

49 printf( d identifiers open at once\n , i);

50 break:

51 }

52 }

53 for (j = 0; j < i; j++)

54 MsgctKqidEj]. IPC RMID, NULL);

55 exitCO);

56 }

Определение максимального размера сообщения

14-28 Для определения максимально возможного размера сообщения мы пытаемся послать сообщение, в котором будет 65 536 байт данных, и если эта попытка оказывается неудачной, уменьшаем этот объем до 65 408, и т. д., пока вызов msgsnd не окажется успешным.

Сколько сообщений различного размера может быть помещено в очередь?

29-44 Теперь мы начинаем с 8-байтовых сообщений и смотрим, сколько их поместится в очередь. После определения этого ограничения мы удаляем очередь (сбрасывая все эти сообщения) и повторяем процедуру с 16-байтовыми сообщениями. Мы повторяем это до тех пор, пока не будет достигнут максимальный размер сообщения из первого пункта. Ожидается, что небольшие сообщения будут превышать ограничение по количеству сообщений в очереди, а большие - ограничение по количеству байтов.

Сколько идентификаторов может быть открыто одновременно?

45-54 Обычно есть системное ограничение на количество одновременно открытых идентификаторов. Оно определяется непосредственно созданием очередей до тех пор, пока не произойдет ошибка при вызове msgget.

Запустим эту программу сначала в Solaris 2.6, азатем в Digital Unix 4.0В, и результаты подтвердят приведенные в табл. 6.2 величины:

Solaris % limits

maximum amount of data per message = 2048 40 8-byte messages were placed on queue. 320 bytes total 40 16-byte messages were placed on queue. 640 bytes total 40 32-byte messages were placed on queue, 1280 bytes total



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