Файл: Литература по курсу аос (по всем вопросам должен быть представлен краткий рукописный конспект в общей тетради).docx
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 08.02.2024
Просмотров: 92
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
постоянно опрашивать переменную на предмет ее состояния.
В ОС Windows NT взаимное исключение реализовано похожим образом, но от этого недостатка избавились: при переводе второго жаждущего потока в ожидание делается отметка, что его нужно освободить после освобождения критической секции.
Понятие семафора и его использование для целей синхронизации.
Семафор – обобщение блокирующих переменных.
Это переменная, которая может принимать целые неотрицательные значения, предложена Дейкстра.
Если семафор может принимать значения только 0 и 1 – он превращается в блокирующую переменную.
Его удобно использовать для синхронизации набора идентичных ресурсов – например, отдельных буферов, с каждым из которых может работать отдельный поток. Они идеальны для решения задачи доступа к ресурсным пулам: информационным структурам, наборам одинаковых областей памяти, наборам внешних устройств.
Здесь у нас 2 семафора, один для количества пустых, второй – для количества занятых буферов.
Синхронизация и проблема тупиков.
При синхронизации процессов может возникнуть проблема взаимной блокировки (дедлок, клинч) или тупика.
Поток-писатель пытается записать данные в заполненный набор буферов – он считывает значение переменной и блокируется в ожидании освобождения хоть одного буфера.
Помочь ему может только поток-читатель, который освободит один буфер.
Но поток-читатель не может войти в критическую секцию, так как она занята потоком – писателем.
Также тупик может возникнуть, когда потоку нужны 2 и более последовательных ресурса, например, принтер и порт.
Поток А запрашивает сначала принтер, потом порт
Поток Б запрашивает сначала порт, затем принтер.
Если поток А получил принтер, был прерван, затем поток Б получил порт и был прерван, потоки не смогут разминуться, так как заняли нужные друг другу ресурсы.
То есть потоки могут образовать очереди к разделяемым ресурсам, но могут и взаимно заблокировать друг друга в зависимости от соотношения их скоростей.
Тупики можно пытаться предотвратить:
- при написании программ задавать одинаковую последовательность запрашивания нескольких ресурсов
- на уровне ОС при запуске задач анализировать возможность возникновения тупика и откладывать запуск опасной задачи.
- выделять ресурсы ОС в определенной, общей для всех потоков последовательности.
Кроме того ОС должна быть снабжена возможностью распознавания уже возникших тупиков (чтобы своевременно снять их)
- ведение и анализ таблиц распределения ресурсов и таблиц запросов к ресурсам
И наконец ОС нужны средства для снятия взаимных блокировок:
- можно снять часть потоков
- можно совершить откат до определенной контрольной точки.
Синхронизирующие объекты в операционных системах.
Рассмотренные выше средства синхронизации всем хороши, только не подходят для синхронизации работы разных потоков (не процессов).
Для этой цели применяются специальные синхронизирующие объекты:
- системные семафоры
- мьютексы
- события таймера и тд
Работа с синхронизирующими объектами похожа на работу с файлами: их можно открывать, закрывать, создавать, уничтожать.
Кроме спецобъектов, для синхронизации могут быть использованы обычные объекты ОС – файлы, процессы, потоки.
Объект синхронизации может находиться в двух состояниях:
Смысл слова «сигнальное» разный для разных объектов (для потока – завершение, для процесса – завершение всех потоков, для файла – завершение всякого ввода-вывода).
С помощью специального системного вызова потоки сообщают ОС, что они хотят синхронизировать свое состояние с определенным ОБЪЕКТОМ СИНХРОНИЗАЦИИ:
Wait(X), где Х – объект синхронизации. Поток, который сделал такой вызов переводится осью в ожидающее состояние, пока объект Х не перейдет в сигнальное состояние.
Чтобы перевести Объект синхронизации в сигнальное состояние, используется другой системный вызов: Set(X);
Поток может ждать сигнального состояния не одного объекта, а нескольких, причем либо всех из них, либо любого из них. Также можно задать Оси время, через которое она должна активизировать поток в любом случае, вне зависимости от состояния объекта синхронизации.
Примеры:
Такие неспецифические объекты синхронизации при переходе в сигнальное состояние активизируют ВСЕ ожидающие потоки, что может быть нужно не всегда.
Иногда надо другое поведение: тогда используются специальные объекты синхронизации: события, мютексы, системные семафоры.
Мютекс и семафор используются для управления доступом к данным.
Мютекс освобождает из очереди только ОДИН поток. Когда поток начинает работу он как бы захватывает мютекс, а по завершении работы – отдает мютекс.
Объект-событие используется для оповещения других потоков о том, что какие-то действия завершены (например, потоки ждут, пока один поток читает данные в буфер памяти.) В начале работы поток-читатель устанавливает объект-событие в несигнальное состояние. Все ждущие потоки поставили wait(поток-событие). После завершения работы поток-читатель переводит объект-событие в сигнальное состояние, и ОС освобождает все ждущие именно этих данных потоки.
Функции ОС по управлению памятью в мультипрограммной среде:
Методы распределения памяти
Разные ОС по-разному распределяют память между процессами
Методы распределения памяти можно разделить на:
- без использования внешней памяти
- фиксированными разделами
- динамическими разделами
- перемещаемыми разделами
- с использованием внешней памяти
- страничное распределение
- сегментное распределение
- сегментно-страничное распределение
Фиксированные разделы
Наиболее простой и примитивный способ распределения памяти. Во время старта или загрузки системы память разбивается на разделы фиксированной величины, после чего границы разделов не сдвигаются.
Новый процесс поступает либо в общую очередь, либо в очередь конкретного раздела.
Система:
- сравнивает требуемый объем памяти с памятью раздела
- загружает программу в один из разделов и настраивает адреса
Недостаток системы:
- жесткость
- уровень мультипрограммирования заранее ограничен числом разделов
- невозможно выполнить прогу, которая больше самого большого раздела
Все же используется в системах реального времени, т.к. там детерминированность компенсирует недостаточную гибкость.
Динамические разделы
ОС должна:
- вести таблицы свободных и занятых областей
- анализировать требования к памяти при создании нового процесса, подыскивать ему незанятую область
- загружать процесс в выделенный ему раздел, корректировать таблицы
- корректировать таблицы после завершения процесса
Плюсы:
- гибче
Минусы – фрагментация памяти.
Так организована память в ОС/360
Перемещаемые разделы
Выделение памяти перемещаемыми разделами призвано решить проблему фрагментации. Суть его – сжатие, то есть перемещение всех занятых участков в сторону старших или младших адресов, чтобы вся свободная память собралась в одном месте.
Ко всем функциям, исполняемым ОС в динамических разделах, добавляется сжатие, которое должно производиться:
- либо при каждом завершении процесса
- либо когда для нового процесса не хватает места.
Физические адреса здесь постоянно меняются, поэтому перемещающий загрузчик для их настройки использовать нельзя, нужно динамическое преобразование адресов
В ОС Windows NT взаимное исключение реализовано похожим образом, но от этого недостатка избавились: при переводе второго жаждущего потока в ожидание делается отметка, что его нужно освободить после освобождения критической секции.
Понятие семафора и его использование для целей синхронизации.
Семафор – обобщение блокирующих переменных.
Это переменная, которая может принимать целые неотрицательные значения, предложена Дейкстра.
Если семафор может принимать значения только 0 и 1 – он превращается в блокирующую переменную.
Его удобно использовать для синхронизации набора идентичных ресурсов – например, отдельных буферов, с каждым из которых может работать отдельный поток. Они идеальны для решения задачи доступа к ресурсным пулам: информационным структурам, наборам одинаковых областей памяти, наборам внешних устройств.
Здесь у нас 2 семафора, один для количества пустых, второй – для количества занятых буферов.
Синхронизация и проблема тупиков.
При синхронизации процессов может возникнуть проблема взаимной блокировки (дедлок, клинч) или тупика.
Поток-писатель пытается записать данные в заполненный набор буферов – он считывает значение переменной и блокируется в ожидании освобождения хоть одного буфера.
Помочь ему может только поток-читатель, который освободит один буфер.
Но поток-читатель не может войти в критическую секцию, так как она занята потоком – писателем.
Также тупик может возникнуть, когда потоку нужны 2 и более последовательных ресурса, например, принтер и порт.
Поток А запрашивает сначала принтер, потом порт
Поток Б запрашивает сначала порт, затем принтер.
Если поток А получил принтер, был прерван, затем поток Б получил порт и был прерван, потоки не смогут разминуться, так как заняли нужные друг другу ресурсы.
То есть потоки могут образовать очереди к разделяемым ресурсам, но могут и взаимно заблокировать друг друга в зависимости от соотношения их скоростей.
Тупики можно пытаться предотвратить:
- при написании программ задавать одинаковую последовательность запрашивания нескольких ресурсов
- на уровне ОС при запуске задач анализировать возможность возникновения тупика и откладывать запуск опасной задачи.
- выделять ресурсы ОС в определенной, общей для всех потоков последовательности.
Кроме того ОС должна быть снабжена возможностью распознавания уже возникших тупиков (чтобы своевременно снять их)
- ведение и анализ таблиц распределения ресурсов и таблиц запросов к ресурсам
И наконец ОС нужны средства для снятия взаимных блокировок:
- можно снять часть потоков
- можно совершить откат до определенной контрольной точки.
Синхронизирующие объекты в операционных системах.
Рассмотренные выше средства синхронизации всем хороши, только не подходят для синхронизации работы разных потоков (не процессов).
Для этой цели применяются специальные синхронизирующие объекты:
- системные семафоры
- мьютексы
- события таймера и тд
Работа с синхронизирующими объектами похожа на работу с файлами: их можно открывать, закрывать, создавать, уничтожать.
Кроме спецобъектов, для синхронизации могут быть использованы обычные объекты ОС – файлы, процессы, потоки.
Объект синхронизации может находиться в двух состояниях:
-
Сигнальное -
Несигнальное
Смысл слова «сигнальное» разный для разных объектов (для потока – завершение, для процесса – завершение всех потоков, для файла – завершение всякого ввода-вывода).
С помощью специального системного вызова потоки сообщают ОС, что они хотят синхронизировать свое состояние с определенным ОБЪЕКТОМ СИНХРОНИЗАЦИИ:
Wait(X), где Х – объект синхронизации. Поток, который сделал такой вызов переводится осью в ожидающее состояние, пока объект Х не перейдет в сигнальное состояние.
Чтобы перевести Объект синхронизации в сигнальное состояние, используется другой системный вызов: Set(X);
Поток может ждать сигнального состояния не одного объекта, а нескольких, причем либо всех из них, либо любого из них. Также можно задать Оси время, через которое она должна активизировать поток в любом случае, вне зависимости от состояния объекта синхронизации.
Примеры:
-
Основной поток создает множество серверных потоков и должен дождаться их завершения – надо сделать wait(x1, x2 и тд). -
Один поток активизируется после завершения другого: надо каждый раз делать wait(предыдущий поток);
Такие неспецифические объекты синхронизации при переходе в сигнальное состояние активизируют ВСЕ ожидающие потоки, что может быть нужно не всегда.
Иногда надо другое поведение: тогда используются специальные объекты синхронизации: события, мютексы, системные семафоры.
Мютекс и семафор используются для управления доступом к данным.
Мютекс освобождает из очереди только ОДИН поток. Когда поток начинает работу он как бы захватывает мютекс, а по завершении работы – отдает мютекс.
Объект-событие используется для оповещения других потоков о том, что какие-то действия завершены (например, потоки ждут, пока один поток читает данные в буфер памяти.) В начале работы поток-читатель устанавливает объект-событие в несигнальное состояние. Все ждущие потоки поставили wait(поток-событие). После завершения работы поток-читатель переводит объект-событие в сигнальное состояние, и ОС освобождает все ждущие именно этих данных потоки.
-
Подсистема управления памятью. Функции ОС по управлению памятью. Методы распределения памяти (фиксированные разделы, динамические разделы, сегментная, страничная, сегментно-страничная структуризация адресного пространства, свопинг, виртуальная память). Организация виртуальной памяти, преобразование адреса. Обмен данными между процессами на основе виртуальной памяти.
Функции ОС по управлению памятью в мультипрограммной среде:
-
Отслеживание свободной и занятой памяти -
Выделение памяти процессам и освобождение по их завершении -
Вытеснение кодов и данных с памяти на диск (полное или частичное) когда памяти не хватает и возвращение их обратно, когда ее достаточно -
Настройка адресов программы на конкретную область физической памяти. -
Динамическое распределение памяти между процессами (выполнение запросов приложений на выделение им дополнительной памяти) -
Дефрагментация памяти -
Защита памяти
Методы распределения памяти
Разные ОС по-разному распределяют память между процессами
Методы распределения памяти можно разделить на:
- без использования внешней памяти
- фиксированными разделами
- динамическими разделами
- перемещаемыми разделами
- с использованием внешней памяти
- страничное распределение
- сегментное распределение
- сегментно-страничное распределение
Фиксированные разделы
Наиболее простой и примитивный способ распределения памяти. Во время старта или загрузки системы память разбивается на разделы фиксированной величины, после чего границы разделов не сдвигаются.
Новый процесс поступает либо в общую очередь, либо в очередь конкретного раздела.
Система:
- сравнивает требуемый объем памяти с памятью раздела
- загружает программу в один из разделов и настраивает адреса
Недостаток системы:
- жесткость
- уровень мультипрограммирования заранее ограничен числом разделов
- невозможно выполнить прогу, которая больше самого большого раздела
Все же используется в системах реального времени, т.к. там детерминированность компенсирует недостаточную гибкость.
Динамические разделы
-
Память изначально свободна и не разбита на разделы -
При поступлении процесса на исполнение ей выдается столько памяти, сколько нужно, если памяти не хватает, то процесс не исполняется -
После завершения процесса память освобождается
ОС должна:
- вести таблицы свободных и занятых областей
- анализировать требования к памяти при создании нового процесса, подыскивать ему незанятую область
- загружать процесс в выделенный ему раздел, корректировать таблицы
- корректировать таблицы после завершения процесса
Плюсы:
- гибче
Минусы – фрагментация памяти.
Так организована память в ОС/360
Перемещаемые разделы
Выделение памяти перемещаемыми разделами призвано решить проблему фрагментации. Суть его – сжатие, то есть перемещение всех занятых участков в сторону старших или младших адресов, чтобы вся свободная память собралась в одном месте.
Ко всем функциям, исполняемым ОС в динамических разделах, добавляется сжатие, которое должно производиться:
- либо при каждом завершении процесса
- либо когда для нового процесса не хватает места.
Физические адреса здесь постоянно меняются, поэтому перемещающий загрузчик для их настройки использовать нельзя, нужно динамическое преобразование адресов