
- •Морис Дж. Бах Архитектура операционной системы unix предисловие
- •Глава 1. Общий обзор особенностей системы
- •1.1 История
- •1.2 Структура системы
- •1.3 Обзор с точки зрения пользователя
- •1.3.1 Файловая система
- •1.3.2 Среда выполнения процессов
- •1.3.3 Элементы конструкционных блоков
- •1.4 Функции операционной системы
- •1.5 Предполагаемая аппаратная среда
- •1.5.1 Прерывания и особые ситуации
- •1.5.2 Уровни прерывания процессора
- •1.5.3 Распределение памяти
- •1.6 Выводы
- •Глава 2. Введение в архитектуру ядра операционной системы
- •2.1 Архитектура операционной системы uniх
- •2.2 Введение в основные понятия системы
- •2.2.1 Обзор особенностей подсистемы управления файлами
- •2.2.2 Процессы
- •2.2.2.1 Контекст процесса
- •2.2.2.2 Состояния процесса
- •2.2.2.3 Переходы из состояния в состояние
- •2.2.2.4 «Сон» и пробуждение
- •2.3 Структуры данных ядра
- •2.4 Управление системой
- •2.5 Выводы и обзор последующих глав
- •2.6 Упражнения
- •Глава 3. Буфер сверхоперативной памяти (кеш)
- •3.1 Заголовки буфера
- •3.2 Структура области буферов (буферного пула)
- •3.3 Механизм поиска буфера
- •3.4 Чтение и запись дисковых блоков
- •3.5 Преимущества и неудобства буферного кеша
- •3.6 Выводы
- •3.7 Упражнения
- •Глава 4. Внутреннее представление файлов
- •4.1 Индексы
- •4.1.1 Определение
- •4.1.2 Обращение к индексам
- •4.1.3 Освобождение индексов
- •4.2 Структура файла обычного типа
- •4.3 Каталоги
- •4.4 Превращение составного имени файла (пути поиска) в идентификатор индекса
- •4.5 Суперблок
- •4.6 Назначение индекса новому файлу
- •4.7 Выделение дисковых блоков
- •4.8 Другие типы файлов
- •4.9 Выводы
- •4.10 Упражнения
- •Глава 5. Системные операции для работы с файловой системой
- •5.1 Open
- •5.2 Read
- •5.3 Wriте
- •5.4 Захват файла и записи
- •5.5 Указание места в файле, где будет выполняться ввод-вывод — lseeк
- •5.6 Closе
- •5.7 Создание файла
- •5.8 Создание специальных файлов
- •5.9 Смена текущего и корневого каталога
- •5.10 Cмена владельца и режима доступа к файлу
- •5.11 Stat и fstат
- •5.12 Каналы
- •5.12.1 Системная функция pipе
- •5.12.2 Открытие поименованного канала
- •5.12.3 Чтение из каналов и запись в каналы
- •5.12.4 Закрытие каналов
- •5.12.5 Примеры
- •5.14 Монтирование и демонтирование файловых систем
- •5.14.1 Пересечение точек монтирования в маршрутах поиска имен файлов
- •5.14.2 Демонтирование файловой системы
- •5.15 Linк
- •5.16 Unlinк
- •5.16.1 Целостность файловой системы
- •5.16.2 Поводы для конкуренции
- •5.17 Абстрактные обращения к файловым системам
- •5.18 Сопровождение файловой системы
- •5.19 Выводы
- •5.20 Упражнения
- •Глава 6. Структура процессов
- •6.1 Состояния процесса и переходы между ними
- •6.2 Формат памяти системы
- •6.2.1 Области
- •6.2.2 Страницы и таблицы страниц
- •6.2.3 Размещение ядра
- •6.2.4 Пространство процесса
- •6.3 Контекст процесса
- •6.4 Сохранение контекста процесса
- •6.4.1 Прерывания и особые ситуации
- •6.4.2 Взаимодействие с операционной системой через вызовы системных функций
- •6.4.3 Переключение контекста
- •6.4.4 Сохранение контекста на случай аварийного завершения
- •6.4.5 Копирование данных между адресным пространством системы и адресным пространством задачи
- •6.5 Управление адресным пространством процесса
- •6.5.1 Блокировка области и снятие блокировки
- •6.5.2 Выделение области
- •6.5.3 Присоединение области к процессу
- •6.5.4 Изменение размера области
- •6.5.5 Загрузка области
- •6.5.6 Освобождение области
- •6.5.7 Отсоединение области от процесса
- •6.5.8 Копирование содержимого области
- •6.6 Приостановка выполнения
- •6.6.1 События, вызывающие приостанов выполнения, и их адреса
- •6.6.2 Алгоритмы приостанова и возобновления выполнения
- •6.7 Выводы
- •6.8 Упражнения
- •Глава 7. Управление процессами
- •7.1 Создание процесса
- •7.2 Сигналы
- •7.2.1 Обработка сигналов
- •7.2.2 Группы процессов
- •7.2.3 Посылка сигналов процессами
- •7.3 Завершение выполнения процесса
- •7.4 Ожидание завершения выполнения процесса
- •7.5 Вызов других программ
- •7.6 Код идентификации пользователя процесса
- •7.7 Изменение размера процесса
- •7.8 Командный процессор shell
- •7.9 Загрузка системы и начальный процесс
- •7.10 Выводы
- •7.11 Упражнения
- •Глава 8. Диспетчеризация процессов и ее временные характеристики
- •8.1 Планирование выполнения процессов
- •8.1.1 Алгоритм
- •8.1.2 Параметры диспетчеризации
- •8.1.3 Примеры диспетчеризации процессов
- •8.1.4 Управление приоритетами
- •8.1.5 Планирование на основе справедливого раздела
- •8.1.6 Работа в режиме реального времени
- •8.2 Системные операции, связанные со временем
- •8.3 Таймер
- •8.3.1 Перезапуск часов
- •8.3.2 Внутренние системные тайм-ауты
- •8.3.3 Построение профиля
- •8.3.4 Учет и статистика
- •8.3.5 Поддержание времени в системе
- •8.4 Выводы
- •8.5 Упражнения
- •Глава 9. Алгоритмы управления памятью
- •9.1 Свопинг
- •9.1.1 Управление пространством на устройстве выгрузки
- •9.1.2 Выгрузка процессов
- •9.1.2.1 Выгрузка при выполнении системной функции fork
- •9.1.2.2 Выгрузка с расширением
- •9.1.3 Загрузка (подкачка) процессов
- •9.2 Подкачка по запросу
- •9.2.1 Структуры данных, используемые подсистемой замещения страниц
- •9.2.1.1 Функция fork в системе с замещением страниц
- •9.2.1.2 Функция exec в системе с замещением страниц
- •9.2.2 "Сборщик" страниц
- •9.2.3 Отказы при обращениях к страницам
- •9.2.3.1 Обработка прерываний по отказу из-за недоступности данных
- •9.2.3.2 Обработка прерываний по отказу системы защиты
- •9.2.4 Замещение страниц на менее сложной технической базе
- •9.3 Система смешанного типа со свопингом и подкачкой по запросу
- •9.4 Выводы
- •9.5 Упражнения
- •Глава 10. Подсистема управления вводом-выводом
- •10.1 Взаимодействие драйверов с программной и аппаратной средой
- •10.1.1 Конфигурация системы
- •10.1.2 Системные функции и взаимодействие с драйверами
- •10.1.2.1 Open
- •10.1.2.2 Closе
- •10.1.2.3 Read и Writе
- •10.1.2.4 Стратегический интерфейс
- •10.1.2.5 Ioctl
- •10.1.2.6 Другие функции, имеющие отношение к файловой системе
- •10.1.3 Программы обработки прерываний
- •10.2 Дисковые драйверы
- •10.3 Терминальные драйверы
- •10.3.1 Символьные списки
- •10.3.2 Терминальный драйвер в каноническом режиме
- •10.3.3 Терминальный драйвер в режиме без обработки символов
- •10.3.4 Опрос терминала
- •10.3.5 Назначение операторского терминала
- •10.3.6 Драйвер косвенного терминала
- •10.3.7 Вход в систему
- •10.4 Потоки
- •10.4.1 Более детальное рассмотрение потоков
- •10.4.2 Анализ потоков
- •10.5 Выводы
- •10.6 Упражнения
- •Глава 11. Взаимодействие процессов
- •11.1 Трассировка процессов
- •11.2 Взаимодействие процессов в версии V системы
- •11.2.1 Сообщения
- •11.2.2 Разделение памяти
- •11.2.3 Семафоры
- •11.2.4 Общие замечания
- •11.3 Взаимодействие в сети
- •11.4 Гнезда
- •11.5 Выводы
- •11.6 Упражнения
- •Глава 12. Многопроцессорные системы
- •12.1 Проблемы, связанные с многопроцессорными системами
- •12.2 Главный и подчиненный процессоры
- •12.3 Семафоры
- •12.3.1 Определение семафоров
- •12.3.2 Реализация семафоров
- •12.3.3 Примеры алгоритмов
- •12.3.3.1 Выделение буфера
- •12.3.3.2 Wait
- •12.3.3.3 Драйверы
- •12.3.3.4 Фиктивные процессы
- •12.4 Система tunis
- •12.5 Узкие места в функционировании многопроцессорных систем
- •12.6 Упражнения
- •Глава 13. Распределенные системы
- •13.1 Периферийные процессоры
- •13.2 Связь типа newcastlе
- •13.3 "Прозрачные" распределенные файловые системы
- •13.4 Распределенная модель без передаточных процессов
- •13.5 Выводы
- •13.6 Упражнения
- •Приложение системные операции
- •Библиография
8.3.4 Учет и статистика
В момент поступления прерывания по таймеру система может выполняться в режиме ядра или задачи, а также находиться в состоянии простоя (бездействия). Состояние простоя означает, что все процессы приостановлены в ожидании наступления события. Для каждого состояния процессора ядро имеет внутренние счетчики, устанавливаемые при каждом прерывании по таймеру. Позже пользовательские процессы могут проанализировать накопленную ядром статистическую информацию.
В пространстве каждого процесса имеются два поля для записи продолжительности времени, проведенного процессом в режиме ядра и задачи. В ходе обработки прерываний по таймеру ядро корректирует значение поля, соответствующего текущему режиму выполнения процесса. Процессы-родители собирают статистику о своих потомках при выполнении функции wait, беря за основу информацию, поступающую от завершающих свое выполнение потомков.
В пространстве каждого процесса имеется также одно поле для ведения учета использования памяти. В ходе обработки прерывания по таймеру ядро вычисляет общий объем памяти, занимаемый текущим процессом, исходя из размера частных областей процесса и его долевого участия в использовании разделяемых областей памяти. Если, например, процесс использует области данных и стека размером 25 и 40 Кбайт, соответственно, и разделяет с четырьмя другими процессами одну область команд размером 50 Кбайт, ядро назначает процессу 75 Кбайт памяти (50К/5 + 25К + 40К). В системе с замещением страниц ядро вычисляет объем используемой памяти путем подсчета числа используемых в каждой области страниц. Таким образом, если прерываемый процесс имеет две частные области и еще одну область разделяет с другим процессом, ядро назначает ему столько страниц памяти, сколько содержится в этих частных областях, плюс половину страниц, принадлежащих разделяемой области. Вся указанная информация отражается в учетной записи при завершении процесса и может быть использована для расчетов с заказчиками машинного времени.
8.3.5 Поддержание времени в системе
Ядро увеличивает показание системных часов при каждом прерывании по таймеру, измеряя время в таймерных тиках от момента загрузки системы. Это значение возвращается процессу через системную функцию time и дает возможность определять общее время выполнения процесса. Время первоначального запуска процесса сохраняется ядром в адресном пространстве процесса при исполнении системной функции fork, в момент завершения процесса это значение вычитается из текущего времени, результат вычитания и составляет реальное время выполнения процесса. В другой переменной таймера, устанавливаемой с помощью системной функции stime и корректируемой раз в секунду, хранится календарное время.
8.4 Выводы
В настоящей главе был описан основной алгоритм диспетчеризации процессов в системе UNIX. С каждым процессом в системе связывается приоритет планирования, значение которого появляется в момент перехода процесса в состояние приостанова и периодически корректируется программой обработки прерываний по таймеру. Приоритет, присваиваемый процессу в момент перехода в состояние приостанова, имеет значение, зависящее от того, какой из алгоритмов ядра исполнялся процессом в этот момент. Значение приоритета, присваиваемое процессу во время выполнения программой обработки прерываний по таймеру (или в тот момент, когда процесс возвращается из режима ядра в режим задачи), зависит от того, сколько времени процесс занимал ЦП: процесс получает низкий приоритет, если он обращался к ЦП, и высокий — в противном случае. Системная функция nice дает процессу возможность влиять на собственный приоритет путем добавления параметра, участвующего в пересчете приоритета. В главе были также рассмотрены системные функции, связанные с временем выполнения системы и протекающих в ней процессов: с установкой и получением системного времени, получением времени выполнения процессов и установкой сигналов "будильника". Кроме того, описаны функции программы обработки прерываний по таймеру, которая следит за временем в системе, управляет таблицей ответных сигналов, собирает статистику, а также подготавливает запуск планировщика процессов, программы подкачки и "сборщика" страниц. Программа подкачки и "сборщик" страниц являются объектами рассмотрения в следующей главе.