
- •Ос как система управления ресурсами
- •Второй период (1955 - 1965)
- •Третий период (1965 - 1980)
- •Четвертый период (1980 - настоящее время)
- •Особенности аппаратных платформ
- •Особенности областей использования
- •Особенности методов построения
- •Одноранговые сетевые ос и ос с выделенными серверами
- •Ос для рабочих групп и ос для сетей масштаба предприятия
- •Состояние процессов
- •Контекст и дескриптор процесса
- •Алгоритмы планирования процессов
- •Вытесняющие и невытесняющие алгоритмы планирования
- •Критическая секция
- •V(s) : переменная s увеличивается на 1 одним неделимым действием; выборка, инкремент и запоминание не могут быть прерваны, и к s нет доступа другим процессам во время выполнения этой операции.
- •Управление памятью
- •Типы адресов
- •Распределение памяти разделами переменной величины
- •Перемещаемые разделы
- •Страничное распределение
- •Сегментное распределение
- •Странично-сегментное распределение
- •Свопинг
- •Иерархия запоминающих устройств. Принцип кэширования данных
- •Средства аппаратной поддержки управления памятью и многозадачной среды в микропроцессорах Intel 80386, 80486 и Pentium
- •Средства поддержки сегментации памяти
- •Сегментно-страничный механизм
- •Средства вызова подпрограмм и задач
- •Организация программного обеспечения ввода-вывода
- •Обработка прерываний
- •Драйверы устройств
- •Независимый от устройств слой операционной системы
- •Пользовательский слой программного обеспечения
- •Файловая система
- •Имена файлов
- •Типы файлов
- •Логическая организация файла
- •Физическая организация и адрес файла
- •Права доступа к файлу
- •Кэширование диска
- •Общая модель файловой системы
- •Отображаемые в память файлы
- •Современные архитектуры файловых систем
- •Способы адресации
- •Блокирующие и неблокирующие примитивы
- •Буферизуемые и небуферизуемые примитивы
- •Надежные и ненадежные примитивы
- •Базовые операции rpc
- •Этапы выполнения rpc
- •Динамическое связывание
- •Семантика rpc в случае отказов
- •Синхронизация в распределенных системах
- •Алгоритм синхронизации логических часов
- •Алгоритмы взаимного исключения
- •Централизованный алгоритм
- •Распределенный алгоритм
- •Алгоритм Token Ring
- •Неделимые транзакции
- •Различные способы организации вычислительного процесса с использованием нитей
- •Вопросы реализации нитей
- •Нити и rpc
- •Распределенные файловые системы
- •Интерфейс файлового сервиса
- •Интерфейс сервиса каталогов
- •Семантика разделения файлов
- •Вопросы разработки структуры файловой системы
- •Кэширование
- •Репликация
- •Гетерогенность
- •Основные подходы к реализации взаимодействия сетей
- •Мультиплексирование стеков протоколов
- •Использование магистрального протокола
- •Вопросы реализации
- •Сравнение вариантов организации взаимодействия сетей
Базовые операции rpc
Чтобы понять работу RPC, рассмотрим вначале выполнение вызова локальной процедуры в обычной машине, работающей автономно. Пусть это, например, будет системный вызов
count=read (fd,buf,nbytes);
где fd - целое число, buf - массив символов, nbytes - целое число.
Чтобы осуществить вызов, вызывающая процедура заталкивает параметры в стек в обратном порядке (рисунок 3.1). После того, как вызов read выполнен, он помещает возвращаемое значение в регистр, перемещает адрес возврата и возвращает управление вызывающей процедуре, которая выбирает параметры из стека, возвращая его в исходное состояние. Заметим, что в языке С параметры могут вызываться или по ссылке (by name), или по значению (by value). По отношению к вызываемой процедуре параметры-значения являются инициализируемыми локальными переменными. Вызываемая процедура может изменить их, и это не повлияет на значение оригиналов этих переменных в вызывающей процедуре.
Если в вызываемую процедуру передается указатель на переменную, то изменение значения этой переменной вызываемой процедурой влечет изменение значения этой переменной и для вызывающей процедуры. Этот факт весьма существенен для RPC.
Существует также другой механизм передачи параметров, который не используется в языке С. Он называется call-by-copy/restore и состоит в необходимости копирования вызывающей программой переменных в стек в виде значений, а затем копирования назад после выполнения вызова поверх оригинальных значений вызывающей процедуры.
Решение о том, какой механизм передачи параметров использовать, принимается разработчиками языка. Иногда это зависит от типа передаваемых данных. В языке С, например, целые и другие скалярные данные всегда передаются по значению, а массивы - по ссылке.
Рис. 3.1. а) Стек до выполнения вызова read; б) Стек во время выполнения процедуры; в) Стек после возврата в вызывающую программу
Идея, положенная в основу RPC, состоит в том, чтобы сделать вызов удаленной процедуры выглядящим по возможности также, как и вызов локальной процедуры. Другими словами - сделать RPC прозрачным: вызывающей процедуре не требуется знать, что вызываемая процедура находится на другой машине, и наоборот.
RPC достигает прозрачности следующим путем. Когда вызываемая процедура действительно является удаленной, в библиотеку помещается вместо локальной процедуры другая версия процедуры, называемая клиентским стабом (stub - заглушка). Подобно оригинальной процедуре, стаб вызывается с использованием вызывающей последовательности (как на рисунке 3.1), так же происходит прерывание при обращении к ядру. Только в отличие от оригинальной процедуры он не помещает параметры в регистры и не запрашивает у ядра данные, вместо этого он формирует сообщение для отправки ядру удаленной машины.
Этапы выполнения rpc
Взаимодействие программных компонентов при выполнении удаленного вызова процедуры иллюстрируется рисунком 3.2. После того, как клиентский стаб был вызван программой-клиентом, его первой задачей является заполнение буфера отправляемым сообщением. В некоторых системах клиентский стаб имеет единственный буфер фиксированной длины, заполняемый каждый раз с самого начала при поступлении каждого нового запроса. В других системах буфер сообщения представляет собой пул буферов для отдельных полей сообщения, причем некоторые из этих буферов уже заполнены. Этот метод особенно подходит для тех случаев, когда пакет имеет формат, состоящий из большого числа полей, но значения многих из этих полей не меняются от вызова к вызову.
Затем параметры должны быть преобразованы в соответствующий формат и вставлены в буфер сообщения. К этому моменту сообщение готово к передаче, поэтому выполняется прерывание по вызову ядра.
Рис. 3.2. Remote Procedure Call
Когда ядро получает управление, оно переключает контексты, сохраняет регистры процессора и карту памяти (дескрипторы страниц), устанавливает новую карту памяти, которая будет использоваться для работы в режиме ядра. Поскольку контексты ядра и пользователя различаются, ядро должно точно скопировать сообщение в свое собственное адресное пространство, так, чтобы иметь к нему доступ, запомнить адрес назначения (а, возможно, и другие поля заголовка), а также оно должно передать его сетевому интерфейсу. На этом завершается работа на клиентской стороне. Включается таймер передачи, и ядро может либо выполнять циклический опрос наличия ответа, либо передать управление планировщику, который выберет какой-либо другой процесс на выполнение. В первом случае ускоряется выполнение запроса, но отсутствует мультипрограммирование.
На стороне сервера поступающие биты помещаются принимающей аппаратурой либо во встроенный буфер, либо в оперативную память. Когда вся информация будет получена, генерируется прерывание. Обработчик прерывания проверяет правильность данных пакета и определяет, какому стабу следует их передать. Если ни один из стабов не ожидает этот пакет, обработчик должен либо поместить его в буфер, либо вообще отказаться от него. Если имеется ожидающий стаб, то сообщение копируется ему. Наконец, выполняется переключение контекстов, в результате чего восстанавливаются регистры и карта памяти, принимая те значения, которые они имели в момент, когда стаб сделал вызов receive.
Теперь начинает работу серверный стаб. Он распаковывает параметры и помещает их соответствующим образом в стек. Когда все готово, выполняется вызов сервера. После выполнения процедуры сервер передает результаты клиенту. Для этого выполняются все описанные выше этапы, только в обратном порядке.
Рисунок 3.3 показывает последовательность команд, которую необходимо выполнить для каждого RPC-вызова, а рисунок 3.4 - какая доля общего времени выполнения RPC тратится на выполнение каждого их описанных 14 этапов. Исследования были проведены на мультипроцессорной рабочей станции DEC Firefly, и, хотя наличие пяти процессоров обязательно повлияло на результаты измерений, приведенная на рисунке гистограмма дает общее представление о процессе выполнения RPC.
Рис. 3.3. Этапы выполнения процедуры RPC
Рис. 3.4. Распределение времени между 14 этапами выполнения RPC
1. Вызов стаба
2. Подготовить буфер
3. Упаковать параметры
4. Заполнить поле заголовка
5. Вычислить контрольную сумму в сообщении
6. Прерывание к ядру
7. Очередь пакета на выполнение
8. Передача сообщения контроллеру по шине QBUS
9. Время передачи по сети Ethernet
10. Получить пакет от контроллера
11. Процедура обработки прерывания
12. Вычисление контрольной суммы
13. Переключение контекста в пространство пользователя
14. Выполнение серверного стаба