Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lit / Kosyakov_-_raspredelennye_sistemy_unlocked.pdf
Скачиваний:
222
Добавлен:
16.03.2016
Размер:
3.86 Mб
Скачать

Вслучае взаимодействия без буферизации, процесс-отправитель направляет получателю запрос на передачу данных и продолжает свою работу. Этот запрос будет ожидать от процесса-получателя готовности к приему данных и соответствующего вызова команды receive(), после чего начнется собственно передача данных. Взаимодействующие процессы смогут узнать об окончании сетевого обмена и, следовательно, о возможности работать с передаваемыми и принимаемыми данными без риска их повреждения с помощью команд, проверяющих признак завершения операций send() или receive(). Эта ситуация иллюстрируется рис. 1.9а.

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

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

1.5.5. Синхронный и асинхронный обмен сообщениями

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

42

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

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

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

Другое преимущество синхронного обмена сообщениями заключается в том, что для передачи сообщения не требуется использования дополнительных буферов, т.к. синхронная операция send() все равно не сможет завершиться, пока не будет вызвана соответствующая операция receive(). Хотя, конечно, возможна реализации этих примитивов и с использованием буферизации. Важно отметить, что синхронная операция receive() после получения сообщения должна отослать соответствующее подтверждение (англ. acknowledgement) отправителю для завершения операции send().

В случае использования блокирующих примитивов взаимодействия передача сообщения с помощью пары вызовов send() и receive() может рассматриваться как одна атомарная операция.

Асинхронный обмен сообщениями. При асинхронном обмене сообщениями не происходит никакой координации между отправителем и получателем сообщения. Для завершения операции send() отправителю не требуется дожидаться приема сообщения процессом-получателем. При отправке нового сообщения, отправителю неизвестно, получено ли его предыдущее сообщение, направленное этому же или, возможно, другому получателю. Поэтому, если канал связи между отправителем и получателем не сохраняет порядок передаваемых по нему сообщений, т.е. не обеспечивает свойство FIFO (англ. First In First Out), получатель может принимать сообщения в другом порядке, нежели они были переданы отправителем. Асинхронной операции receive() нет необходимости отсылать отправителю подтверждение (англ. acknowledgement) о приеме сообщения.

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

43

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

44

Соседние файлы в папке Lit