Рейтинговые книги
Читем онлайн Архитектура операционной системы UNIX - Морис Бах

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 98 99 100 101 102 103 104 105 106 ... 127

С сообщениями работают четыре системных функции: msgget, которая возвращает (и в некоторых случаях создает) дескриптор сообщения, определяющий очередь сообщений и используемый другими системными функциями, msgctl, которая устанавливает и возвращает связанные с дескриптором сообщений параметры или удаляет дескрипторы, msgsnd, которая посылает сообщение, и msgrcv, которая получает сообщение.

Синтаксис вызова системной функции msgget:

msgqid = msgget(key, flag);

где msgqid — возвращаемый функцией дескриптор, а key и flag имеют ту же семантику, что и в системной функции типа "get". Ядро хранит сообщения в связном списке (очереди), определяемом значением дескриптора, и использует значение msgqid в качестве указателя на массив заголовков очередей. Кроме вышеуказанных полей, описывающих общие для всего механизма права доступа, заголовок очереди содержит следующие поля:

• Указатели на первое и последнее сообщение в списке;

• Количество сообщений и общий объем информации в списке в байтах;

• Максимальная емкость списка в байтах;

• Идентификаторы процессов, пославших и принявших сообщения последними;

• Поля, указывающие время последнего выполнения функций msgsnd, msgrcv и msgctl.

Когда пользователь вызывает функцию msgget для того, чтобы создать новый дескриптор, ядро просматривает массив очередей сообщений в поисках существующей очереди с указанным идентификатором. Если такой очереди нет, ядро выделяет новую очередь, инициализирует ее и возвращает идентификатор пользователю. В противном случае ядро проверяет наличие необходимых прав доступа и завершает выполнение функции.

Для посылки сообщения процесс использует системную функцию msgsnd:

msgsnd(msgqid, msg, count, flag);

где msgqid — дескриптор очереди сообщений, обычно возвращаемый функцией msgget, msg — указатель на структуру, состоящую из типа в виде назначаемого пользователем целого числа и массива символов, count — размер информационного массива, flag — действие, предпринимаемое ядром в случае переполнения внутреннего буферного пространства.

алгоритм msgsnd /* послать сообщение */

входная информация:

 (1) дескриптор очереди сообщений

 (2) адрес структуры сообщения

 (3) размер сообщения

 (4) флаги

выходная информация: количество посланных байт

{

 проверить правильность указания дескриптора и наличие соответствующих прав доступа;

 do while (для хранения сообщения не будет выделено место) {

  if (флаги не разрешают ждать) return;

  sleep (до тех пор, пока место не освободится);

 }

 получить заголовок сообщения;

 считать текст сообщения из пространства задачи в пространство ядра;

 настроить структуры данных: выстроить очередь заголовков сообщений, установить в заголовке указатель на текст сообщения, заполнить поля, содержащие счетчики, время последнего выполнения операций и идентификатор процесса;

 вывести из состояния приостанова все процессы, ожидающие разрешения считать сообщение из очереди;

}

Рисунок 11.4. Алгоритм посылки сообщения

Ядро проверяет (Рисунок 11.4), имеется ли у посылающего сообщение процесса разрешения на запись по указанному дескриптору, не выходит ли размер сообщения за установленную системой границу, не содержится ли в очереди слишком большой объем информации, а также является ли тип сообщения положительным целым числом. Если все условия соблюдены, ядро выделяет сообщению место, используя карту сообщений (см. раздел 9.1), и копирует в это место данные из пространства пользователя. К сообщению присоединяется заголовок, после чего оно помещается в конец связного списка заголовков сообщений. В заголовке сообщения записывается тип и размер сообщения, устанавливается указатель на текст сообщения и производится корректировка содержимого различных полей заголовка очереди, содержащих статистическую информацию (количество сообщений в очереди и их суммарный объем в байтах, время последнего выполнения операций и идентификатор процесса, пославшего сообщение). Затем ядро выводит из состояния приостанова все процессы, ожидающие пополнения очереди сообщений. Если размер очереди в байтах превышает границу допустимости, процесс приостанавливается до тех пор, пока другие сообщения не уйдут из очереди. Однако, если процессу было дано указание не ждать (флаг IPC_NOWAIT), он немедленно возвращает управление с уведомлением об ошибке. На Рисунке 11.5 показана очередь сообщений, состоящая из заголовков сообщений, организованных в связные списки, с указателями на область текста.

Рисунок 11.5. Структуры данных, используемые в организации сообщений

Рассмотрим программу, представленную на Рисунке 11.6. Процесс вызывает функцию msgget для того, чтобы получить дескриптор для записи с идентификатором MSGKEY. Длина сообщения принимается равной 256 байт, хотя используется только первое поле целого типа, в область текста сообщения копируется идентификатор процесса, типу сообщения присваивается значение 1, после чего вызывается функция msgsnd для посылки сообщения. Мы вернемся к этому примеру позже.

Процесс получает сообщения, вызывая функцию msgrcv по следующему формату:

count = msgrcv(id, msg, maxcount, type, flag);

где id — дескриптор сообщения, msg — адрес пользовательской структуры, которая будет содержать полученное сообщение, maxcount — размер структуры msg, type — тип считываемого сообщения, flag — действие, предпринимаемое ядром в том случае, если в очереди сообщений нет. В переменной count пользователю возвращается число прочитанных байт сообщения.

Ядро проверяет (Рисунок 11.7), имеет ли пользователь необходимые права доступа к очереди сообщений. Если тип считываемого сообщения имеет нулевое значение, ядро ищет первое по счету сообщение в связном списке. Если его размер меньше или равен размеру, указанному пользователем, ядро копирует текст сообщения в пользовательскую структуру и соответствующим образом настраивает свои внутренние структуры: уменьшает счетчик сообщений в очереди и суммарный объем информации в байтах, запоминает время получения сообщения и идентификатор процесса-получателя, перестраивает связный список и освобождает место в системном пространстве, где хранился текст сообщения. Если какие-либо процессы, ожидавшие получения сообщения, находились в состоянии приостанова из-за отсутствия свободного места в списке, ядро выводит их из этого состояния. Если размер сообщения превышает значение maxcount, указанное пользователем, ядро посылает системной функции уведомление об ошибке и оставляет сообщение в очереди. Если, тем не менее, процесс игнорирует ограничения на размер (в поле flag установлен бит MSG_NOERROR), ядро обрезает сообщение, возвращает запрошенное количество байт и удаляет сообщение из списка целиком.

#include ‹sys/types.h›

#include ‹sys/ipc.h›

#include ‹sys/msg.h›

#define MSGKEY 75

struct msgform {

 long mtype;

 char mtext[256];

};

main() {

 struct msgform msg;

 int msgid, pid, *pint;

 msgid = msgget(MSGKEY, 0777);

 pid = getpid();

 pint = (int *) msg.mtext;

 *pint = pid; /* копирование идентификатора процесса в область текста сообщения */

 msg.mtype = 1;

 msgsnd(msgid, &msg, sizeof(int), 0);

 msgrcv(msgid, &msg, 256, pid, 0);

 /* идентификатор процесса используется в качестве типа сообщения */

 printf("клиент: получил от процесса с pid %dn", *pint);

}

Рисунок 11.6. Пользовательский процесс

алгоритм msgrcv /* получение сообщения */

входная информация:

 (1) дескриптор сообщения

 (2) адрес массива, в который заносится сообщение

 (3) размер массива

 (4) тип сообщения в запросе

 (5) флаги

выходная информация: количество байт в полученном сообщении

{

 проверить права доступа;

loop:

 проверить правильность дескриптора сообщения;

 /* найти сообщение, нужное пользователю */

 if (тип сообщения в запросе == 0)

  рассмотреть первое сообщение в очереди;

 else

if (тип сообщения в запросе › 0)

    рассмотреть первое сообщение в очереди, имеющее данный тип;

  else /* тип сообщения в запросе ‹ 0 */

   рассмотреть первое из сообщений в очереди с наименьшим значением типа при условии, что его тип не превышает абсолютное значение типа, указанного в запросе;

1 ... 98 99 100 101 102 103 104 105 106 ... 127
На этой странице вы можете бесплатно читать книгу Архитектура операционной системы UNIX - Морис Бах бесплатно.
Похожие на Архитектура операционной системы UNIX - Морис Бах книги

Оставить комментарий