P1
|
P2
|
send(&a, 1, 2);
receive(&b, 1, 2);
|
send(&a, 1, 1);
receive(&b, 1, 1);
|
Приведенный выше фрагмент кода призван обеспечить передачу значений переменных "а" между процессами P1 и P2. Однако в случае, если команды send() и receive() реализованы согласно механизму блокирующей отправки/ получения без буферизации, то примитив send() в процессе P1 будет ожидать вызова соответствующей команды receive() в процессе P2, а примитив send() в процессе P2 будет ожидать вызова receive() в P1. В результате оба процесса будут находиться в состоянии ожидания и оказываются заблокированными навсегда.
Блокирующие операции буферизованной отправки/ получения. Простым решением проблем, связанных с возникновением взаимных блокировок, указанных выше, и простоем процессов, ожидающих готовности к приему-передаче данных от других процессов, является использование дополнительных буферов на отправляющей и принимающей стороне. В этом случае передаваемые данные просто копируются из буфера процесса-отправителя в дополнительный буфер отправки (обычно размещаемый в адресном пространстве операционной системы). При этом команда send() возвращает управление вызвавшему ее процессу сразу после того, как завершится операция копирования, и процесс-отправитель сможет продолжать свою работу, т.к. любые изменения данных с его стороны уже не будут влиять на семантику передачи сообщения.
Стоить отметить, что принимаемые данные не могут быть сохранены непосредственно в адресном пространстве процесса-получателя пока он не будет готов к приему и не вызовет команду receive(). Иначе его нормальное исполнение может быть нарушено. Поэтому наличие дополнительного буфера приема на стороне получателя, куда следует помещать принимаемые данные, также является обязательным. Когда же процесс-получатель достигнет состояния готовности к приему данных, он вызовет команду receive(), которая проверит буфер приема, и если в нем
находится новое сообщение, скопирует его содержимое в целевой буфер в адресном пространстве принимающего процесса.
Описанная выше схема взаимодействия опирается на наличие двух дополнительных буферов отправки и приема, соответственно, на стороне отправителя и на стороне получателя. Кроме того подразумевается, что сам обмен данными осуществляется специальной коммуникационной подсистемой, работающей независимо от исполняемых процессов. Если подобные средства недоступны, то проблемы блокирующей отправки/ получения без буферизации могут быть решены путем введения только одного буфера, располагающегося на одной стороне, например, на стороне получателя. В этом случае операция send() должна будет прервать работу принимающего процесса, оба процесса должны будут самостоятельно осуществить передачу и сохранение данных в дополнительный буфер приема на стороне получателя, после чего процесс-получатель продолжит работу. В дальнейшем, когда принимающий процесс вызовет команду receive(), данные будут скопированы из буфера приема в целевой буфер в адресном пространстве получателя.
Механизм блокирующего буферизованного взаимодействия для случая двух дополнительных буферов отправки и приема иллюстрируется рис. 1.8.
Рис. 1.8. Механизм блокирующей буферизованной отправки/ получения;
(а) первым осуществляется вызов send(), (б) первым осуществляется вызов receive().
Легко видеть, что при использовании механизма буферизованной отправки и получения вместо издержек, вызванных простоем процессов, ожидающих приема или передачи данных, появляются накладные расходы, связанные с выделением дополнительной памяти, копированием данных в буфер / из буфера, управлением дополнительными буферами. В случае,
когда распределенная система является синхронной (т.е. когда команды send() и receive() вызываются приблизительно в одно и то же время), отправка и получение данных без буферизации может быть даже более эффективной и производительной, чем буферизованная передача. Тем не менее, для более общего случая асинхронных систем буферизованное взаимодействие будет являться предпочтительным до тех пор, пока емкость буфера не станет ограничивающим фактором. Для понимания влияния буферов конечного размера на передачу сообщений рассмотрим следующий пример:
Do'stlaringiz bilan baham: |