
- •Глава 4
- •В.Г.Олифер, н.А.Олифер. Сетевые операционные системы. Учебное пособие.-сПб.:бхв-Петербург, 2006.-536с.
- •В.А.Шеховцов. Операційні системи. Підручник .-к.:Виканавча група внv. 2005. 576с.
- •Столлингс в. Операционные системы. М.: Вильямс, 2001. -672с.
- •Раздел 4
- •4.1. Виды межпроцесорного взаимодействия
- •4.1.1. Методы распределения памяти
- •4.1.2. Методы передачи сообщений
- •4.1.3. Технология отображаемой памяти
- •4.1.4. Особенности межпроцесорного взаимодействия
- •4.2. Базовые механизмы межпроцессового взаимодействия
- •4.2.1. Межпроцессовое взаимодействие на базе общей памяти
- •4.2.2. Основы передачи сообщений
- •4.2.3. Технологии передачи сообщений
4.2.3. Технологии передачи сообщений
Рассмотрим методы передачи сообщений, которые применяют на практике.
-
Каналы
Канал - это простейшее средство передачи сообщений.
Он является циклическим буфером, запись в который выполняют с помощью одного процесса, а чтение – с помощью другого. В конкретный момент времени к каналу имеет доступ только один процесс. Операционная система обеспечивает синхронизацию согласно правилу: если процесс старается записывать в канал, в котором нет места, или старается считать больше данных, чем помещено в канал, он переходит в состояние ожидания.
Различают безымянные и именные каналы.
К безымянным каналам нет доступа с помощью средств именования, поэтому процесс не может открыть уже имеющийся безымянный канал без его дескриптора. Это означает, что такой процесс должен получить дескриптор канала от процесса, который его создал, а это возможно только для связанных процессов.
К именным каналам (named pipes) доступ осуществляется по именам. Такому каналу может отвечать, например, файл в файловой системе, при этом любой процесс, который имеет доступ к этому файла, может обмениваться данными через соответствующий канал. Поименованые каналы реализуют косвенный обмен данными.
Обмен данными через канал может быть односторонним и двусторонним.
-
Очереди сообщений
Другой технологией асинхронного косвенного обмена данными являются применение очередей сообщений. Для таких очередей выделяют специальное место в системном участке памяти ОС, доступное для приложений пользователя. Процессы могут создавать новые очереди, отсылать сообщение в конкретную очередь и получать их оттуда. С очередью одновременно может работать несколько процессов.
Сообщение - это структуры данных сменной длины.
Для того чтобы процессы могли различать адресованные им сообщение, каждому из них присваивают тип. Отосланное сообщение остается в очереди до тех пор, пока не будет считанное. Синхронизация во время работы с очередями похожа на синхронизацию для каналов.
-
Сокеты
Наиболее расспространенным методом обмена сообщениями являются использования сокетов (sockets). Эта технология прежде всего предназначена для организации сетевого обмена данными, но может быть использованная и для взаимодействия между процессами на одном компьютере (собственно, сетевое взаимодействие можно понимать как обобщение ІРС).
Сокет - это абстрактная конечная точка соединения, через которую процесс может отсылать или получать сообщение.
Обмен данными между двумя процессами осуществляют через пару сокетов, по одном на каждый процесс. Абстрактность сокета заключается в том, что он скрывает особенности реализации передачи сообщений - после того как сокет создан, работа с ним не зависит от технологии передачи данных, поэтому один и тот самый код можно без больших изменений использовать для работы с разными протоколами связи.
Особенности протокола передачи данных и формирование адреса сокета определяет коммуникационный домен; его нужно отмечать во время создания каждого сокета. Примерами доменов могут быть домен Интернета (который задает протокол связи на базе ТСР/ІР) и локальный домен или домен UNIX, который реализует связь с использованием имени файла (подобно одноименному каналу).
Сокет можно использовать в объединении только с одним коммуникационным доменом. Адрес сокета зависит от домена (например, для сокетов домену UNIX таким адресом будет имя файла).
Способы передачи данных через сокет определяются его типом. В конкретном домене могут поддерживаться или не поддерживаться разные типы сокетoв.
Например, и для домена Интернет, и для домена UNIX поддерживаются сокеты таких типов:
-
потоковый (stream sockets) - задают надежный двусторонний обмен данными сплошным потоком без выделения границ (операция чтения данных возвращает столько данных, сколько запрошено или сколько было на этот момент переданo);
-
дейтаграмный (datagram sockets) - задают ненадежный двусторонний обмен сообщениями с выделением границ (операция чтения данных возвращает размер того сообщения, которое было отослано).
Во время обмена данными с использованием сокетoв обычно применяется технология клиент-сервер, когда один процесс (сервер) ожидает соединение, а другой (клиент) соединяют с ним.
Перед тем как начать работать с сокетами, любой процесс (и клиент, и сервер) должны создать сокет с помощью системного вызова sockets(). Параметрами этого вызова задают коммуникационный домен и тип сокета. Этот вызов возвращает сокету дескриптор - уникальное значение, с помощью которого можно будет обращаться к этому сокету.
Дальнейшие действия отличаются для сервера и клиента. Сначала рассмотрим последовательность шагов, которую нужно выполнить для сервера.
-
Сокет связывается с адресом с помощью системного вызова bind().
Для сокетов домена UNIX как адрес задают имя файла, для сокетов домена Интернет - необходимые характеристики сетевого соединения.
Дальше клиент для установления соединения и обмена сообщениями будет указывать этот адрес.
-
Сервер дает возможность клиентам устанавливать соединение, выполнив системный вызов listen() для дескриптора сокета, созданного раньше.
-
После выхода из системного вызова listen() сервер готов принимать от клиентов запрос на соединение. Эти запросы выстраиваются в очередь. Для получения запроса из этой очереди и создание соединения используют системный вызов assept(). Вследствие его выполнения у применение возвращают новый сокет для обмена данными с клиентом. Старый сокет можно использовать дальше для приема новых запросов на соединение. Если во время вызова assept() запрос на соединение в очереди отсутствуют, сервер переходит в состояние ожидания.
Для клиента последовательность действий после создания сокета совсем другая. Вместо трех шагов достаточно выполнить один - установить соединение с использованием системного вызова correct(). Параметрами этого вызова задают дескриптор созданного раньше сокета, а также адрес, подобный указанного на сервере для вызова bind().
После установления соединения (и на клиенте, и на сервере) появится возможность передавать и принимать данные с использованием этого соединения. Для передачи данных применяют системный вызов send(), а для приема — recv(). Указанную последовательность шагов используют для установления надежного соединения. Если все, что нам нужно, - это отослать и принять конкретное сообщение фиксированной длины, то соединение можно и не создавать совсем. Для этого как отправитель, так и получатель сообщения должны предварительно связать сокет с адресами через вызов bind(). Потом можно воспользоваться вызовами прямой передачи данных: sendto() - для отправителя и recvfrom() - для получателя. Параметрами этих вызовов задают адреса получателя и отправителя, а также адреса буферов для данных.
-
Отдаленный вызов процедур
Технология отдаленного вызова является примером синхронного обмена сообщениями с подтверждением получения.
Рассмотрим последовательность шагов, необходимых для обмена данными в этом случае.
-
Операцию send оформляют как вызов процедуры с параметрами.
-
После вызова такой процедуры отправитель переходит в состояние ожидания, а данные (имя процедуры и параметры) доставляются получателю. Получатель может находиться на том самом компьютере, или на отдаленной машине; технология КРС скрывает это. Классический отдаленный вызов процедур предусматривает, что процесс-получатель создаётся вследствие запроса.
-
Получатель выполняет операцию receive и на основании поступивших данных выполняет соответствующие действия (вызывает локальную процедуру по имени, передает ей параметры и вычисляет результат).
-
Вычисленный результат возвращают отправителю как отдельное сообщение.
-
После получения этого сообщения отправитель продолжает свою работу, рассматривая вычисленный результат как следствие вызова процедуры.
Выводы
-
Потоки разных процессов, которые взаимодействуют, должны использовать средства межпроцессорного взаимодействия, задачами которой являются обеспечения обмена данными между защищенными адресными пространствами, а также их синхронизация. К основным видам межпроцессорного взаимодействия принадлежат передачи сообщений, распределенная и отображаемая память.
-
Главной особенностью передачи сообщений является то, что эта технология не требует наличия совместно используемых данных. Процессы обмениваются сообщениями сменной длины с помощью примитивов send и receive. Эта технология может быть применена для организации взаимодействия между процессами, выполняемыми на отдаленных компьютерах.
Контрольные вопросы и задачи
-
Предположим, что к коммуникационному каналу, предоставленному ОС, могут «подключаться» два процесса. Какие синхронизационные примитивы на равные ядра ОС могут быть использованы для обмена данными этим каналом соответственно технологии программных каналов (ріреs)? В качестве примера ОС возьмите систему Linux.
-
Пересчитайте возможные отличия реализации очереди сообщений и программного канала на равные ядра ОС.
-
Система обмена сообщениями предоставляет примитивы send и receive. Примитив receive приостанавливает процесс, если нет сообщений, предназначенных для него. Возможное ли взаимное блокирование процессов, если не учитывать других сообщений, а общих данных у процессов нет?
-
Пересчитайте общие черты и отличия именованых каналов и сокетов.