Буферизация в примитивах передачи сообщений

 

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

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

Буферизация не требуется и при другом варианте обмена сообщениями, когда процесс-отправитель посылает сообщение в сеть, не дожидаясь прихода от полу­чателя подтверждения о готовности к приему. Затем процесс-отправитель бло­кируется либо до прихода такого подтверждения (в этом случае никакой допол­нительной работы с данным сообщением не выполняется), либо до истечения тайм-аута, после которого сообщение посылается вновь, причем в случае много­кратных повторных неудачных попыток сообщение отбрасывается.

В обоих случаях сообщение непосредственно из памяти процесса-отправителя попадает в сеть, а после прихода из сети — в память процесса-получателя, минуя буфер, поддерживаемый системой. Однако такая организация на практике в се­тевых операционных системах не применяется, так как в первом варианте про­цесс-получатель может достаточно долго ждать, пока сообщение будет передано по сети (в большой составной сети, например в Интернете, задержки могут до­стигать нескольких секунд), а во втором — из-за неготовности процесса-получателя сообщение может многократно бесполезно передаваться по сети, засоряя каналы связи.

Именно поэтому при использовании синхронных примитивов все же предусмат­ривают буферизацию. При этом буфер, как правило, выбирается размером в одно сообщение, так как процесс-отправитель не может послать следующее сообще­ние, не получив подтверждения о приеме предыдущего. Сообщение помещается в буфер, поддерживаемый операционной системой компьютера-получателя, если в момент его прихода процесс-получа1ель не может обработать сообщение не­медленно, например из-за того, что процесс либо не является текущим, либо не готов к приему сообщения, так как не обратился к примитиву receive. Буфер может располагаться как в системной области памяти, так и в области памяти пользовательского процесса, в любом случае буфером управляет операционная система, модули которой получают сообщения по сети.

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

Обычно операционная система предоставляет для прикладных процессов специ­альный примитив для создания буферов сообщений. Такого рода примитив, на­зовем его, например, create_buffer (создать буфер), процесс должен использовать перед тем, как отправлять или получать сообщения с помощью примитивов send и receive. При создании буфера его размер может либо устанавливаться по умол­чанию, либо выбираться прикладным процессом. Часто такой буфер носит на­звание порта (port), или почтового ящика (mailbox).

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

узнать, какому процессу адресовано вновь поступившее сообщение, если имеет­ся несколько активных процессов? И как оно узнает, куда его скопировать? Один из вариантов — просто отказаться от сообщения в расчете на то, что отпра­витель после тайм-аута передаст сообщение повторно и к этому времени полу­чатель уже создаст буфер. Этот подход не сложен в реализации, но, к сожале­нию, отправитель (или скорее ядро его компьютера) может сделать несколько таких безуспешных попыток. Еще хуже то, что после достаточно большого числа безуспешных попыток ядро отправителя может сделать неправильный вывод об аварии на машине получателя или о неправильности его адреса. Второй подход к этой проблеме заключается в том, чтобы хранить хотя бы не­которое время поступающие сообщения в ядре получателя в расчете на то, что вскоре будет выполнен соответствующий примитив createbuffer. Каждый раз, когда поступает такое «неожидаемое» сообщение, включается таймер. Если за­данный временной интервал истекает раньше, чем происходит создание буфера, то сообщение теряется.

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








Дата добавления: 2015-06-10; просмотров: 1710;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.004 сек.