Главная страница Взаимодействие нетривиальных процессов канал и при считывании из канала родительским процессом. Для ускорения обработки порожденный процесс может создать сегмент совместно используемой с породившим процессом памяти, а канал использовать как флаг (упражнение 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. Характерные значения ограничений для очередей сообщений
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
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |