Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Олифер. Сетевые операционные системы.docx
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
16.5 Mб
Скачать

Синхронизация

Центральным вопросом взаимодействия процессов в сети является способ их синхронизации, который полностью определяется используемыми в операционной системе коммуникационными примитивами. В этом отношении коммуникационные примитивы делятся на блокирующие (синхронные) и неблокирующие (асинхронные), причем смысл данных терминов в целом соответствует смыслу аналогичных терминов, применяемых при описании системных вызо­вов (см. раздел «Системные вызовы» в главе 4) и операций ввода-вывода (см. раздел «Синхронный и асинхронный режимы» в главе 7). В отличие от локаль­ных системных вызовов (а именно такие системные вызовы были рассмотрены в главах 4 и 7), при выполнении коммуникационных примитивов завершение запрошенной операции в общем случае зависит от работы не только локальной, но и удаленной ОС.

Коммуникационные примитивы могут быть оформлены в операционной системе двояко: как внутренние процедуры ядра ОС (в этом случае они могут работать только с модулями ОС) или как системные вызовы (доступные в этом случае процессам в пользовательском режиме).

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

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

  • Опрос (polling). Этот подход предусматривает наличие еще одного базового примитива test (проверить), с помощью которого процесс-получатель может анализировать состояние буфера.

  • Прерывание (interrupt). В этом случае программное прерывание уведомляет процесс-получателя о том, что сообщение помещено в буфер. Хотя такой подход очень эффективен (он исключает многократные проверки состояния буфера), у него имеется существенный недостаток — усложненное программирование, связанное с прерываниями пользовательского уровня, то есть прерываниями, по которым вызываются процедуры пользовательского ре­жима (например, вызов АРС-процедур в ОС Windows NT при завершении операции ввода-вывода, рассмотренный в главе 8).

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

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

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

Рис. 10.4. Синхронное взаимодействие с помощью блокирующих примитивов send и receive

В противном случае взаимодействие считается асинхронным (рис. 10.5).

Рис. 10.5. Асинхронное взаимодействие с помощью неблокирующих примитивов send и receive

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

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