Здравствуйте!
В лекциях этого модуля рассмотрим механизмы,
связанные с синхронизацией и обменом информацией
между процессами и потоками.
В операционных системах процессы, работающие
совместно, могут сообща
использовать некое общее хранилище данных.
Каждый процесс может считывать из общего хранилища данных
и записывать туда информацию.
Таким хранилищем может быть участок разделяемой памяти
или файл общего доступа.
Природа хранилища данных не влияет на суть проблемы.
А какие проблемы могут возникнуть?
Рассмотрим простой пример: спулер печати.
Если процессу требуется вывести на печать файл,
он помещает имя файла в специальный каталог спулера.
Другой процесс — демон печати —
периодически просматривает наличие файлов,
которые нужно печатать, и печатает файл,
после этого удаляет его имя из каталога.
Пусть каталог спулера — это большое число сегментов,
пронумерованных от 0 до n,
в каждом из которых может храниться имя файла.
Также есть две совместно используемые, общие переменные:
out, описывающая на следующий файл для печати,
и in, указывающая на следующий свободный сегмент.
Допустим ситуацию, что два процесса A и B
одновременно решают поставить файл в очередь на печать.
Чем это грозит?
Процесс A считывает значение переменной in
и запоминает его значение (например, 7).
После этого происходит прерывание по таймеру
и процессор переключается на процесс B.
Процесс B тоже считывает значение переменной in
и опять же его запоминает как "7".
В данный момент оба процесса считают,
что следующий свободный сегмент — седьмой.
Затем происходит прерывание по таймеру
и процессор переключается обратно на процесс А
и он продолжает с того места, где его перехватили,
а именно с того момента, когда он собирался
поместить имя нужного файла в спулер
и меняет значение in на 8.
На этом процесс А завершается.
Тем временем, управление передается процессу В,
который сохраняет в каталоге спулера
имя нужного ему файла.
Так как он до сих пор считает,
что следующая свободная ячейка 7,
он в нее помещает нужное имя файла,
затем как ни в чем не бывало,
поменяет значение in на 8
и не будет чувствовать угрызений совести.
Демон, в свою очередь, ничего подозрительного
не заметит и распечатает файл,
нужный процессу В в ячейке 7,
а процесс А останется ни с чем, хотя будет считать,
что его файл распечатан.
Состояние состязания — ситуация,
в которой два и более процесса
считывают или записывают данные одновременно
и конечный результат зависит от того,
кто из них был первым.
Основной способ избежать состязания —
это запрет одновременной записи
из нескольких разделяемых данных
более, чем одним процессом.
Иными словами, необходимо взаимное исключение.
Это означает, что в тот момент,
когда один процесс использует разделенные данные,
другому процессу это делать будет запрещено.
Проблема, описанная выше, возникла из-за того,
что процесс В начал работу с совместно
используемой переменной до того, как
процесс А ее закончит.
Сформулируем проблему исключения состязаний
на абстрактном уровне.
Некоторый промежуток времени процесс занят
внутренними расчетами и другими задачами,
не приводящими к состоянию состязания.
В другие моменты времени процесс
обращается к совместно используемым данным,
называемой критической областью.
Если удастся избежать одновременного нахождения
в критических областях, мы сможем избежать состязаний.
Условия правильного использования общих данных.
2 процесса не должны одновременно
находиться в критических областях.
В программе не должно быть предположений
о скорости или количестве процессоров.
Процесс, находящийся вне критической области,
не может блокировать другие процессы.
Невозможна ситуация, в которой процесс
вечно ждет попадания в критическую область.
Реализация задач синхронизации осуществляется
с помощью механизмов (средств) синхронизации.
Такие механизмы многочисленны по способам реализации,
степени эффективности и областям
использования в различных операционных системах.
Чаще всего эти механизмы имеют
программно-аппаратную форму реализации
и основаны на использовании специальных переменных,
разделяемых и глобально доступных
параллельным взаимодействующим процессам.
Средства синхронизации,
имеющие машинно-ориентированный характер,
и требующие от пользователей всякий раз специальных
программ для решения какой-либо задачи синхронизации
называются низкоуровневыми.
Средства синхронизации, реализованные в виде
программной системы, назначением которой
является решение конкретной задачи синхронизации,
называются высокоуровневыми.
Они доступны пользователям через специальный интерфейс.
Особенности решения конкретной задачи синхронизации
высокоуровневыми средствами скрыты от пользователей.
Любое высокоуровневое средство синхронизации
можно реализовать с помощью низкоуровневых средств.