Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТЕМА_5 - ОС - Лекция 2.doc
Скачиваний:
81
Добавлен:
10.06.2015
Размер:
5.38 Mб
Скачать

5.8.3. Вызов удаленных процедур

Удобным способом взаимодействия ОС и приложений в сети является вызов удаленных процедур (Remote Procedure Call, RPC). Этот механизм представляет собой надстройку над системой обмена сообщениями ОС, поэтому в ряде случаев он позволяет более удобно и прозрачно организовать взаимодействие программ в сети, однако его полезность не универсальна [28].

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

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

1. Вызов процедуры - широко распространенная, используемая и понятная абстракция.

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

3. Поскольку интерфейсы стандартизованы и точно определены, коммуникационный код может генерироваться автоматически.

4. По этой же причине разработчики могут создавать клиентские и серверные модули, которые требуют минимальных доработок при переносе между различными компьютерными платформами и операционными системами.

Характерными чертами вызова локальных процедур являются:

• асимметричность - одна из взаимодействующих сторон является инициатором взаимодействия;

• синхронность - выполнение вызывающей процедуры блокируется с момента выдачи запроса и возобновляется только после возврата из вызываемой процедуры.

Хотя идея вызова удаленных процедур состоит в расширении хорошо известного и понятного механизма передачи управления и данных внутри программы, выполняющейся на одной машине, реализация удаленных вызовов существенно сложнее. Во-первых, вызывающая и вызываемая процедуры выполняются на разных машинах, а поэтому имеют разные адресные пространства. Это создает проблемы при передаче параметров и результатов, особенно если машины и их операционные системы не идентичны.

• Следующим отличием RPC от локального вызова является то, что он обязательно использует нижележащую систему обмена сообщениями, однако это не должно быть явно видно ни в определении процедур, ни в самих процедурах.

Другое отличие: выполнение вызывающей и вызываемой локальной процедур в одной машине реализуется в рамках единого процесса, а в реализации RPC участвуют как минимум два процесса - по одному в каждой машине. В случае, если один из них аварийно завершится, могут возникнуть следующие ситуации:

• при аварийном завершении вызывающей процедуры удаленно вызванные процедуры становятся ≪осиротевшими≫;

•при аварийном завершении удаленных процедур становятся ≪обездоленными родителями≫ вызывающие процедуры, которые будут безрезультатно ожидать ответа от удаленных процедур.

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

Чтобы понять работу RPC, рассмотрим сначала выполнение вызова локальной процедуры в автономном компьютере. Пусть это будет процедура записи данных в файл:

М = my_write (fd, buf, length);

Здесь fd - дескриптор файла (целое число), buf - указатель на массив символов, length - длина массива (целое число).

Чтобы осуществить вызов, вызывающая процедура помещает указанные параметры в стек в обратном порядке и передает управление вызываемой процедуре my_write. Эта пользовательская процедура после некоторых манипуляций с данными символьного массива buf выполняет системный вызов write для записи данных в файл, передавая ему параметры тем же способом, т. е. помещая их в стек (при реализации системного вызова они копируются в стек системы, а при возврате из него результат помещается в пользовательский стек). После того как процедура my_write выполнена, она помещает возвращаемое значение m в регистр, перемещает адрес возврата и возвращает управление вызывающей про__ которая выбирает параметры из стека, возвращая его в ис

Заметим, что в языке С параметры могут вызываться по ссылке (by name), представляющей собой адрес глобальной области памяти, в которой хранится параметр, или по значению (by value) в этом случае параметр копируется из исходной области памяти в локальную память процедуры, располагаемую обычно в стековом сегменте. В первом случае вызываемая процедура работает с оригинальными значениями параметров и их изменения сразу же видны вызывающей процедуре. Во втором случае вызываемая процедура работает с копиями значений параметров и их изменения никак не влияют на значение оригиналов этих переменных в вызывающей процедуре. Эти обстоятельства весьма существенны для RPC.

Решение о том, какой механизм передачи параметров использовать, принимается разработчиками языка. Иногда это зависит от типа передаваемых данных. В языке С, например, целые и другие скалярные данные всегда передаются по значению, а массивы - по ссылке.

Рис. 5.27 иллюстрирует передачу параметров вызываемой процедуре: стек до выполнения вызова write (а), стек во времени выполнения процедуры (б), стек после возврата в вызывающую программу (в).

Идея, положенная в основу RPC, состоит в том, чтобы вызов удаленной процедуры по возможности выглядел так же, как и вызов локальной процедуры, т. е. чтобы он был прозрачным для программиста: вызывающей процедуре не требуется знать, что вызываемая процедура находиться на другой машине, и наоборот.__

рис 5.27

Механизм RPC достигает прозрачности следующим образом. Когда вызываемая процедура действительно является удаленной, в библиотеку процедур вместо локальной реализации оригинального кода процедуры помещается другая версия процедуры, называемая клиентским стабом (stub - заглушка). На удаленный компьютер, который выполняет роль сервера процедур, помещается оригинальный код вызываемой процедуры, а также еще один стаб, называемый серверным стабом. Назначение стабов - организовать передачу параметров вызываемой процедуре и возврат значения процедуры через сеть, при этом код оригинальной процедуры, помещенной на сервер, должен быть полностью сохранен.

Стабы используют для передачи данных через сеть средства подсистемы обмена сообщениями, т. е. существующие в ОС примитивы send и receive. Иногда в подсистеме обмена сообщениями выделяется программный модуль, организующий связь стабов с примитивами передачи сообщений, называемый модулем RPCRuntime.

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

рис 5.28

Эта операция называется операцией упаковки параметров. После этого клиентский стаб обращается к примитиву send для передачи этого сообщения удаленному компьютеру, на который помещена реализация оригинальной процедуры. Получив из сети сообщение, ядро ОС удаленного компьютера вызывает серверный стаб, который извлекает из сообщения параметры и вызывает обычным образом оригинальную процедуру.

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

Серверный стаб распаковывает параметры вызова, имеющиеся в сообщении, и обычным образом вызывает оригинальную процедуру, передавая ей параметры через стек. После окончания работы процедуры серверный стаб упаковывает результат ее работы в новое сообщение и с помощью примитива send передает сообщение по сети клиентскому стабу, а тот возвращает обычным образом результат и управление вызывающей процедуре. Ни вызывающая, ни оригинальная процедуры не изменились от того, что они стали работать на разных компьютерах.

Стабы могут генерироваться вручную или автоматически. В первом случае программист использует средства, предоставляемые ему разработчиком средств RPC, но это достаточно объемная работа. При автоматическом способе применяется специальный язык определения интерфейса (Interface Definition Language), с помощью которого программист описывает интерфейс между клиентом и сервером RPC [28].

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

При постоянном связывании (persistent binding) установленная при вызове процедуры связь не уничтожается после окончания вызова. Поэтому она может использоваться и для других вызовов удаленных процедур. Если в течение предопределенного времени не осуществляется ни один вызов, такая связь с целью экономии ресурсовраз рывается. Этот метод хорошо подходит для интенсивного вызова удаленных процедур, позволяя множеству вызовов использовать одно и то же соединение.

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

Для обеспечения большей гибкости и большей степени параллельности реализуются различные варианты асинхронного RPC, сохраняющие простоту и удобство традиционных вызовов удаленных процедур. Асинхронные вызовы не блокируют вызывающую программу. Ответ может быть получен вызывающей программой тогда, когда он ей потребуется, так что клиент может продолжать работу параллельно с обработкой его запроса сервером.__

Обычно асинхронный RPC используется для того, чтобы позволить клиенту сделать несколько запросов к серверу, каждый со своим набором данных, не дожидаясь его ответов. Синхронизация клиента и сервера при этом может быть выполнена одним из двух способов:

1. Приложение-клиент дожидается ответа на все отправленные запросы.

2. По окончании выполнения последовательности асинхронных RPC клиент выполняет синхронный вызов удаленной процедуры. Сервер ответит на синхронный вызов только после окончания обработки всех предшествующих асинхронных вызовов.