Синхронизация
Центральным вопросом взаимодействия процессов в сети является способ их синхронизации, который полностью определяется используемыми в операционной
системе коммуникационными примитивами. В этом отношении коммуникационные примитивы делятся на блокирующие {синхронные) инеблокирующие (асинхронные), причем смысл данных терминов в целом соответствует смыслу аналогичных терминов, применяемых при описании системных вызовов (см. подраздел «Системные вызовы» раздела «Мультипрограммирование на основе прерываний» в главе 4 «Процессы и потоки») и операций ввода-вывода (см. подраздел «Поддержка синхронных и асинхронных операций ввода-вывода» раздела «Задачи ОС по управлению файлами и устройствами» в главе 7 «Ввод-вывод и файловая система»). В отличие от локальных системных вызовов (а именно такие системные вызовы были рассмотрены в главах 4 и 7) при выполнении коммуникационных примитивов завершение запрошенной операции в общем случае зависит не только от некоторой работы локальной ОС, но и от работы удаленной ОС.
Коммуникационные примитивы могут быть оформлены в операционной системе двумя способами: как внутренние процедуры ядра ОС (в этом случае ими могут использоваться только модули ОС) или как системные вызовы (доступные в этом случае процессам в пользовательском режиме).
При использовании блокирующего примитива send процесс, выдавший запрос на его выполнение, приостанавливается до момента получения по сети сообщения-подтверждения о том, что приемник получил отправленное сообщение. А вызов блокирующего примитива receiveприостанавливает вызывающий процесс до момента, когда он получит сообщение. При использовании неблокирующих примитивов send иreceive управление возвращается вызывающему процессу немедленно, сразу после того, как ядру передается информация о том, где в памяти находится буфер, в который нужно поместить сообщение, отправляемое в сеть или ожидаемое из сети. Преимуществом этой схемы является параллельное выполнение вызывающего процесса и процедур передачи сообщения (не обязательно работающих в контексте вызвавшего соответствующий примитив процесса).
Важным вопросом при использовании неблокирующего примитива receive является выбор способа уведомления процесса-получателя о том, что сообщение пришло и помещено в буфер. Обычно для этой цели требуется один из двух способов.
□ Опрос (polling). Этот метод предусматривает наличие еще одного базового примитива test (проверить), с помощью которого процесс-получатель может анализировать состояние буфера.
□ Прерывание (interrupt). Этот метод использует программное прерывание для уведомления процесса-получателя о том, что сообщение помещено в буфер. Хотя такой метод и очень эффективен (он исключает многократные проверки состояния буфера), у него имеется существенный недостаток — усложненное программирование, связанное с прерываниями пользовательского уровня, то есть прерываниями, по которым вызываются процедуры пользовательского режима (например, вызов процедур АРС в ОС Windows NT по завершении операции ввода-вывода, рассмотренный в главе 8 «Дополнительные возможности файловых систем»).
При использовании блокирующего примитива send может возникнуть ситуация, когда процесс-отправитель блокируется навсегда. Например, если процесс получатель потерпел крах или же отправленное сообщение было утеряно из-за сетевой ошибки. Чтобы предотвратить такую ситуацию, блокирующий примитив send часто использует механизм тайм-аута. То есть определяется интервал времени, после которого операция send завершается со статусом «ошибка». Механизм тайм-аута может использоваться также блокирующим примитивом receive для предотвращения блокировки процесса-получателя на неопределенное время, когда процесс-отправитель потерпел крах или сообщение было потеряно вследствие сетевой ошибки.
Если при взаимодействии двух процессов оба примитива — send и receive — являются блокирующими, говорят, что процессы взаимодействуют по сети синхронно (рис. 9.4), в противном случае взаимодействие считается асинхронным (рис. 9.5).
По сравнению с асинхронным взаимодействием синхронное является более простым, его легко реализовать. Оно также более надежно, так как гарантирует процессу-отправителю, возобновившему свое выполнение, что его сообщение было получено. Главный же недостаток — ограниченный параллелизм и возможность возникновения клинчей.
Обычно в ОС имеется один из двух видов примитивов, но ОС является более гибкой, если поддерживает как блокирующие, так и неблокирующие примитивы.
Дата добавления: 2015-06-10; просмотров: 1103;