Сетевые операционные системы

       

Порты


Основой всех коммуникаций в Mach является структура данных ядра, называемая порт. В сущности порт представляет собой защищенный почтовый ящик. Когда нить одного процесса хочет взаимодействовать с нитью другого процесса, то нить-отправитель записывает сообщение в такой порт, а нить-получатель извлекает его оттуда. Каждый порт имеет средства защиты, которые гарантируют, что только процессы, имеющие соответствующие права, могут передавать и получать через него сообщения.

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

Порты поддерживают надежный и последовательный обмен сообщениями. Если нить посылает сообщения в порт, то система гарантирует, что оно будет доставлено. Сообщения никогда не теряются из-за ошибок, переполнения или других причин (по крайней мере, если нет отказов аппаратуры). Также гарантируется, что сообщения, отправленные одной нитью, будут получены в том же порядке. Если же две нити пишут в один и тот же порт попеременно, то система не дает никаких гарантий о последовательности сообщений, так как в ядре сообщения буферизуются. В отличие от конвейера, порты поддерживают поток не байтов, а сообщений. Несколько сообщений никогда не соединяются вместе в одно сообщение.

Структура порта показана на рисунке 6.8.

Рис 6.8. Структура порта

Когда порт создается, выделяется 64 байта из пространства ядра и они используются до тех пор, пока порт не разрушен, либо явно, либо косвенно, при определенных обстоятельствах, например, когда не окажется в наличии ни одного процесса, который использует этот порт. Порт содержит поля, указанные на рисунке 6.8, а также еще несколько второстепенных.

Сами сообщения хранятся не в порте, а в другой структуре данных ядра, называемой очередь сообщений.
Порт содержит счетчик, в котором хранится текущее количество сообщений, находящихся в очереди, и максимально возможное число сообщений в очереди. Если порт относится к какому-либо набору портов, то порт хранит указатель на структуру данных набора портов. Как уже было кратко упомянуто выше, процесс может предоставить другим процессам права на использование его портов. По различным причинам ядро должно знать, сколько прав каждого типа предоставлено, поэтому порт хранит их количество.

Если при использовании порта возникает ошибка, то о ней сообщается путем посылки сообщений на другие порты, чьи права хранятся здесь. Нити могут быть заблокированы при чтении из порта, поэтому в структуру порта включен указатель на список заблокированных нитей. Также важна возможность нахождения прав на чтение из порта (он может быть только один), поэтому такая информация тоже хранится в структуре данных порта. Если порт представляет собой порт процесса, то следующее поле содержит указатель на процесс, к которому порт относится. Если это порт нити, то это поле содержит указатель на структуру данных ядра для нити, и так далее. Имеется также несколько дополнительных полей, не описанных здесь.

Когда нить создает порт, то в ответ она получает целое число, идентифицирующее порт, аналогичное дескриптору файла в UNIX. Это число используется в последовательных вызовах, с помощью которых посылаются сообщения порту или принимаются сообщения от него, для того, чтобы идентифицировать, какой порт нужно использовать. Порты хранятся для процессов, а не для нитей, так что если одна нить создает порт и получает в ответ идентификатор 3, то другая нить того же процесса никогда не получит этот идентификатор при создании порта. Фактически ядро не запоминает информацию о том, какая нить какой порт создала.

Нить может передать права доступа к порту другой нити другого процесса. Ясно, что нельзя проделать это просто помещением соответствующего целого числа в сообщение, так же как и UNIX-процесс не может передать дескриптор файла для стандартного устройства вывода путем записи 1 в конвейер.Используемый для этого механизм защищен ядром, мы обсудим его позже. В данный момент времени важно только знать, что это можно сделать.

На рисунке 6.9 мы видим ситуацию, в которой два процесса, А и В, имеют доступ к одному и тому же порту. Процесс А послал сообщение для данного порта, а процесс В прочитал это сообщение. Заголовок и тело сообщения физически копируются из А в порт, а затем из порта в В.



Рис. 6.9. Передача сообщений через порт

Для удобства порты можно группировать в наборы портов. Порт может относится максимум к одному набору портов. Можно произвести операцию чтения из набора


Содержание раздела