- •1.Архитектура операционных систем
- •1.1Общие вопросы архитектуры операционных систем
- •1.2Архитектура Windows
- •1.2.1История возникновения Windows
- •1.2.2Архитектура ос Windows
- •1.2.3История возникновения ос Linux
- •1.2.4Архитектура Linux
- •1.2.5Интерфейсы системы unix
- •1.2.6Файловая система unix
- •1.2.7Аутентификация в unix
- •1.2.8Сценарии командной оболочки unix
- •1.3Операционная система qnx
- •1.3.1 Архитектура qnx
- •1.4Выводы
- •1.5Вопросы для самоконтроля
- •2.Типы и алгоритмы работы с оперативной памятью
- •2.1Общие принципы функционирования подсистемы памяти в ос
- •2.1.1Обобщённые принципы управления памятью
- •2.1.2Однозадачная система без подкачки на диск
- •2.1.3Многозадачность с фиксированными разделами
- •2.1.4Подкачка
- •2.1.5Управление памятью с помощью битовых массивов
- •2.1.6Управление памятью с помощью связанных списков
- •2.1.7Виртуальная память
- •2.1.8Многоуровневые таблицы страниц
- •2.1.9Алгоритмы замещения страниц
- •2.2Виртуальная память ос Windows
- •2.2.1Архитектура памяти в ос Windows
- •2.2.2Работа с виртуальной памятью в ос Windows
- •2.2.3Использование виртуальной памяти в приложениях
- •2.3Пример организации страничной памяти на примере linux
- •2.3.1Страничная организация памяти в Linux
- •2.3.2Права доступа к области памяти
- •2.3.3Работа с областями памяти в Linux
- •3.Процессы и потоки
- •3.1Процессы
- •3.1.1Модель процесса
- •3.1.2Создание процесса
- •3.1.3Завершение процесса
- •3.1.4Состояния процессов
- •3.1.5Реализация процессов
- •3.2Потоки
- •3.2.1Реализация потоков
- •3.2.2Реализация потоков на уровне ядра
- •3.2.3Смешанная реализация
- •3.2.4 Метод управления «Активация планировщика»
- •3.2.5Всплывающие потоки
- •3.3Межпроцессное взаимодействие
- •3.3.1Состояние состязания
- •3.3.2Критические секции (Критические области)
- •3.3.3Взаимное исключение с активным ожиданием
- •3.3.4Примитивы межпроцессного взаимодействия
- •3.4Семафоры
- •3.5Мьютексы
- •3.6Организация многопоточной обработки в среде Windows
- •3.6.1Объекты ядра Windows
- •3.6.2Потоки Windows
- •3.6.3Синхронизация потоков в Windows
- •3.6.4Синхронизация потоков с помощью объектов ядра
- •3.6.5Сравнение объектов, используемых для синхронизации потоков
- •3.7Организация процессов и потоков в Linux
- •3.7.1Среда окружения в Linux
- •3.7.2Создание нового процесса. Системный вызов exec.
- •3.7.3Потоки unix. Функции потоков стандарта posix.
- •3.8Синхронизация потоков в unix
- •3.8.1Мьютексы
- •3.8.2Семафоры
- •0,0,0, //Ожидать обнуления семафора
- •0,1,0 // Затем увеличить значение семафора на 1};
- •0,1, 0 // Увеличитьзначение семафора на 1};
3.2.2Реализация потоков на уровне ядра
Теперь рассмотрим ситуацию, в которой ядро знает о существовании потоков и управляет ими. В этом случае система поддержки исполнения программ не нужна, как показано на рис. 3.5, б. Нет необходимости и в наличии таблицы потоков в каждом процессе, вместо этого есть единая таблица потоков, отслеживающая все потоки системы. Если потоку необходимо создать новый поток или завершить имеющийся, он выполняет запрос ядра, который создает или завершает поток, внося изменения в таблицу потоков.
Таблица потоков, находящаяся в ядре, содержит регистры, состояние и другую информацию о каждом потоке. Информация та же, что и в случае управления потоками на уровне пользователя, только теперь она располагается не в пространстве пользователя (внутри системы поддержки исполнения программ), а в ядре. Эта информация является подмножеством информации, которую традиционное ядро хранит о каждом из своих однопоточных процессов (то есть подмножеством состояния процесса). Дополнительно ядро содержит обычную таблицу процессов, отслеживающую все процессы системы.
Все запросы, которые могут блокировать поток, реализуются как системные запросы, что требует значительно больших временных затрат, чем вызов процедуры системы поддержки исполнения программ. Когда поток блокируется, ядро по желанию запускает другой поток из этого же процесса (если есть поток в состоянии готовности) либо поток из другого процесса. При управлении потоками на уровне пользователя система поддержки исполнения программ запускает потоки из одного процесса, пока ядро не передает процессор другому процессу (или пока не кончаются потоки, находящиеся в состоянии готовности).
Поскольку создание и завершение потоков в ядре требует относительно больших расходов, некоторые системы используют повторное использование потоков. После завершения поток помечается как нефункционирующий, но в остальном его структура данных, хранящаяся в ядре, не затрагивается. Позже, когда нужно создать новый поток, реактивируется отключенный поток, что позволяет сэкономить на некоторых накладных расходах. При управлении потоками на уровне пользователя повторное использование потоков тоже возможно, но поскольку накладных расходов, связанных с управлением потоками, в этом случае существенно меньше, то и смысла в этом меньше.
Управление потоками в ядре не требует новых не блокирующих системных запросов. Более того, если один поток вызвал ошибку из-за отсутствия страницы, ядро легко может проверить, есть ли в этом процессе потоки в состоянии готовности, и запустить один из них, пока требуемая страница считывается с диска. Основным недостатком управления потоками в ядре является существенная цена системных запросов, поэтому постоянные операции с потоками (создание, завершение и т. п.) приведут к увеличению накладных расходов.
3.2.3Смешанная реализация
С целью совмещения преимуществ реализации потоков на уровне ядра и на уровне пользователя были опробованы многие способы смешанной реализации. Один из методов заключается в использовании управления ядром и последующем мультиплексировании потоков на уровне пользователя, как показано на рис. 3.6.
Рис. 3.6. Смешанная реализация потоков
В такой модели ядро знает только о потоках своего уровня и управляет ими. Некоторые из этих потоков могут содержать по нескольку потоков пользовательского уровня, мультиплексированных поверх них. Потоки пользовательского уровня создаются, завершаются и управляются так же, как потоки уровня пользователя в процессе, запущенном в не поддерживающей многопоточность системе. Предполагается, что у каждого потока ядра есть набор потоков на уровне пользователя, которые используют его по очереди.