Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Деревянко_БС ЭВМ

.pdf
Скачиваний:
66
Добавлен:
31.05.2015
Размер:
3.6 Mб
Скачать

гих потоков, модель СОМ поддерживает многопотоковый апартамент (МТА).

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

Апартаменты создаются библиотеками функций СОМ. Желаемый тип апартамента клиент указывает при создании кокласса.

Режим работы системы СОМ с внутрипроцессными объектами задается в реестре в подключе InproсServer32 в поле

Threading Model. Поле Threading Model может принимать одно из четырех значений:

none (не задано) – объект располагается в самом первом созданном в процессе STA (главный STA). Объект в главном STA абсолютно потокоустойчив.

Apartment – объекты будут загружены в какой-нибудь STA процесса. Потокоустойчивость данных также гарантируется. Использование глобальных и статических данных должно быть запрограммировано безопасным в смысле потоков образом.

Free – свободная потоковая модель (МТА). Объекты следует проектировать потокоустойчивыми.

Both – объект может работать в STA или в МТА, в зависимости от структуры клиента. Объекты должны быть абсолютно потокобезопасными.

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

51

границы процессов и машин, но и через границы апартаментов. То есть:

если процесс имеет несколько STA, и объект в одном STA запрашивает доступ к объекту в другом STA, загружаются заглушки и прокси;

если объект в единственном процессе МТА хочет работать с объектом в STA, загружаются заглушки и прокси.

1.4.Удаленный вызов процедур (RPC)

1.4.1.Работа программы, использующей RPC

Прикладной программный интерфейс высокого уровня, должен изолировать программу от специфики сетевого взаимодействия. В данном разделе мы рассмотрим один из таких подходов - удаленный вызов процедур (Remote Procedure Call, RFC). На его базе, в частности, разработана файловая система NFS и технология Microsoft - СОМ.

Удаленный вызов процедуры включает следующие ша-

ги.

1.Программа-клиент производит локальный вызов процедуры, называемой заглушкой (stub). При этом клиенту «кажется», что, вызывая заглушку, он производит вызов процеду- ры-сервера: клиент передает заглушке необходимые параметры, а она возвращает результат. Однако задача заглушки — принять аргументы, предназначаемые удаленной процедуре, возможно, преобразовать их в некий стандартный формат и сформировать сетевой запрос. Упаковка аргументов и создание сетевого запроса называется сборкой (marshalling).

2.Сетевой запрос пересылается по сети на удаленную систему. Для этого в заглушке используются соответствующие вызовы. При этом могут быть использованы различные транспортные протоколы, причем не только семейства TCP/IP.

3.На удаленном хосте все происходит в обратном по-

52

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

4.Заглушка выполняет вызов настоящей процедурысервера, которой адресован запрос клиента, передавая ей полученные по сети аргументы.

5.После выполнения процедуры управление возвращается в заглушку сервера. Как и заглушка клиента, заглушка сервера преобразует возвращенные процедурой значения, формируя сообщение-отклик, который передается по сети системе, от которой пришел запрос.

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

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

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

53

1.4.2. Разработка программы, использующей RPC

Передача параметров

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

Связывание (binding)

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

нахождение удаленного хоста с требуемым сервером;

нахождение требуемого серверного процесса на дан-

ном хосте.

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

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

54

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

Для передачи запроса клиенту также необходимо знать сетевой адрес хоста и номер порта, связанный с программойсервером, обеспечивающей требуемые процедуры. Для этого используется демон portmap (в некоторых системах он называется rpcbind). Демон – это неинтерактивная программа, не связанная ни с каким сеансом пользователя. Демон запускается на хосте, который предоставляет сервис удаленных процедур, и использует общеизвестный номер порта. При запуске процесса-сервера он регистрирует в portmap свои процедуры и номера портов. Теперь, если клиенту требуется знать номер порта для вызова конкретной процедуры, он посылает запрос на сервер portmap.

Вызов

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

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

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

Максимум раз. Это означает, что процедура либо во-

55

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

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

Протоколы

RPC занимает промежуточное место между уровнем приложения и транспортным уровнем. Этому положению соответствуют уровни представления и сеанса. Таким образом, RPC теоретически независим от сетевых протоколов транспортного уровня.

Сообщения передаются, как правило, с использованием протоколов TCP или UDP. Выбор того или иного протокола зависит от требований приложения. Выбор протокола UDP оправдан для приложений, обладающих следующими характеристиками.

1.Вызываемые процедуры не накапливают изменения.

2.Размер передаваемых аргументов и возвращаемого результата меньше размера пакета UDP — 8 Кбайт.

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

TCP обеспечивает эффективную работу приложений со следующими характеристиками.

1.Приложению требуется надежный протокол пе-

56

редачи.

2.Вызываемые процедуры накапливают измене-

ния.

3.Размер аргументов или возвращаемого результата превышает 8 Кбайт.

Выбор протокола обычно остается за клиентом, и система по-разному организует формирование и передачу сообщений. Так, при использовании протокола TCP, для которого передаваемые данные представляют собой поток байтов, необходимо отделять сообщения друг от друга. Для этого, например, применяется протокол маркировки записей, описанный в

RFC1057 (1987 г.) «RPC: Remote Procedure Call Protocol specification version 2», при котором в начале каждого сообщения помещается 32-разрядное целое число, определяющее размер сообщения в байтах.

В большинстве реализаций RPC используются стандартные виды представления данных, к которым должны быть преобразованы все значения, передаваемые в запросах и откликах. Например, в RPC фирмы Sun Microsystems порядок следования байтов: старший — последний.

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

57

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

Например, RPC фирмы Sun Microsystems состоит из трех основных частей:

rpcgen — RPC-компилятор, который на основании описания интерфейса удаленной процедуры генерирует заглушки клиента и сервера в виде программ на языке С.

Библиотека XDR (external Data Representation), кото-

рая содержит функции преобразования данных в стандартный вид для обмена между разнородными системами.

Библиотека модулей, обеспечивающих работу системы в целом.

1.4.3. Пример

Распределенное приложение для ведения журнала событий. Клиент при запуске вызывает удаленную процедуру записи сообщения в файл журнала удаленного компьютера.

Для этого придется создать как минимум три файла: спецификацию интерфейсов удаленных процедур log.x (на особом языке описания интерфейса), собственно текст удаленных процедур log.c и текст головной программы клиента main( ) — client.с (на языке С). Есть реализации RPC, где используется IDL.

Компилятор rpcgen на основании спецификации log.x создает три файла: текст заглушек клиента и сервера на языке С (log_clnt.c и log_svc.c) и файл описаний log.h, используемый обеими заглушками.

58

lоg.х

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

program LOG_PROG { version LOG_VER {

int RLOG(string) = 1;

}= 1; // Номер версии

}= 0x31234567; // Номер программы

Компилятор rpcgen создает файл заголовков log.h.

log.h

#ifndef _LOG_H_RPCGEN #define _LOG_H_RPCGEN #include <rpc/rpc.h> /*Номер программы*/

#define LOG_PROG ((unsigned long) (0x31234567))

#define LOG_VER ( (unsigned long) (1))

/*Номер версии*/

#define RLOG ( (unsigned long) (1))

/*Номер процедуры*/ extern int *rlog_l();

/*Внутренняя процедура — нам ее использовать не придется*/

extern int log_prog_l_freeresult(); #endif /* !_LOG_H_RPCGEN */

59

Компилятор транслирует имя RLOG, определенное в файле описания интерфейса, в rlog_1, заменяя прописные символы строчными и добавляя номер версии программы с подчеркиванием. Тип возвращаемого значения изменился с int на int * (указатель на int). RPC позволяет передавать и получать только адреса объявленных при описании интерфейса параметров. Это же правило касается и передаваемой в качестве аргумента строки. Хотя из файла log.h это не следует, на самом деле в качестве аргумента функции rlog_1 также передается адрес строки.

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

Заглушка сервера является головной программой, обрабатывающей все сетевое взаимодействие с клиентом. Для выполнения операции заглушка сервера производит локальный вызов функции rlog_1, текст которой необходимо написать.

log.c

#include <rpc/rpc.h> #include <sys/types.h> #include <sys/stat.h> #include "log.h"

int *rlog_1(char **arg)

{

/*Возвращаемое значение должно определяться как static*/

static int result;

int fd; /*Файловый дескриптор журнала*/ int len;

result = 1;

/*Откроем файл журнала (создадим, если он не существует), в случае неудачи вернем код ошибки

result = 1.*/ if((fd=open("/server.log",O_CREAT |

60

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]