Что такое операционная система и как она работает?

Примечание

Основа конспекта, лекция - Что такое операционная система и как она работает Автор конспекта/статьи немного переработал и дополнил некоторые моменты: структуру и повествование, постарался дать более глубокое и последовательное разъясление, добавил как скаченные, так и созданные им лично схемы.

Цель конспекта — последовательно рассмотреть и объяснить принципы устройства и функционирования операционной системы, её основных компонентов и абстракций.



Введение

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

Любой компьютер представляет собой связанную совокупность: процессора, памяти и устройств ввода-вывода.

Рис. 1. Общее представление архитектуры компьютера

Рис. 1. Общее представление архитектуры компьютера

Сама по себе, аппаратура умеет делать только очень простые, базовые операции - по типу: сложить два числа, перейти к адресу, записать по адресу и тд.

Например, процессор умеет выполнять только четыре базовых типа инструкции:

  • Чтение инструкций/данных из памяти (read)
  • Выполнение интрукции (execute)
  • Запись результата в память (write)
  • Прерывание (interrupt)

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

Возникает вопрос — Как заставить всё это слаженно и эффективно работать, сделав пользование компьютером удобным как для обычного человека, так и для прикладного программиста?

Чтобы ответить на этот вопрос более последовательно, немного заглянем туда, откуда всё начиналось.

Немного истории

На заре компьютерной эпохи, первые компьютеры представляли собой огромные блоки (занимавшие большие комнаты), в которых размещались основные его компоненты: процессор, память и устройства ввода-вывода. И всего можно было выделить два состояния, в котором, в реальном времени находится компьютерная система:

  • Ввод/Вывод
  • Вычисление

Внимание

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

Идея многопользовательского режима в использовании ресурсов компьютера нашла свою реализацию в понятии процесс. То есть, каждый процесс - это пользователь ресурсов компьютера.

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

Примечание

Далее, термины: процесс, приложение идут как синонимы термину пользователь ресурсов.

Зачем нужна Операционная Система?

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

Существует три ключевых элемента операционной системы:

  1. Абстракции (процессы, потоки, файлы, сокеты, адресное пространство).
  2. Функции (создание, управление, открытие, запись, распределение).
  3. Конкретные реализации
    • Архитектуры: монолитные, модульные, гибридные;
    • Алгоритмы: LRU, EDF;

Фунции ОС

  • Управление ресурсами и процессами, а также совместное использование вычислительных ресурсов группой приложений (многозадачность) — центральная функция ОС, которая является базой для разных системных архитектур
    • Scheduler — планировщик. Механизм управляющий процессами и реализующий многозадачность.
    • Memory manager — менеджер памяти. Механизм выделяющий память и управляющий ею.
  • Абстракция оборудования для удобства и переносимости
    • то есть реализация единого интерфейса для разного, но схожего по функциям оборудования.
  • Изоляция ошибок приложений друг от друга (и от ядра ОС)
  • Переносимость данных между приложениями (процессами)
    • Inter Process Communication (IPC) — Механизм межпроцессного взаимодействия
    • файлы и файловая система

Основные абстракции ОС

  • Процессы и потоки - программы, что находятся в оперативной памяти и обрабатываются процессором. Другими словами - исполнение программы.
  • Файлы и файловые системы - некоторая структура данных и связи между этими структурами, универсальный системный интерфейс.
  • Адресное пространство и память - распределение и управление памятью.
  • Сокеты, протоколы, устройства - интерфейсы взаимодействия.

Положение ОС в многоуровневой иерархии организации компьютера

Современный компьютер можно представить в виде иерархии уровней (от двух и более), где на каждом уровне выделяются свои абстракции и набор возможных функций.

Рис. 2. Основные уровни устройства ПК

Рис. 2. Основные уровни устройства ПК

Операционная система является одним из таких уровней и представляет собой интерфейс («прослойку») между пользователем ресурсов компьютера и самими ресурсами, управляющий взаимодействиями как между пользователь-ресурс, так и пользователь-пользователь, устройство-устройство.

В целом, общей схемой это можно отобразить так:

Рис. 3. Место ОС в компьютерной системе

Рис. 3. Место ОС в компьютерной системе

Примечание

  • App - пользователь ресурсов;
  • Hardware - оборудование;
  • Proc - Процессор;
  • Memory - Оперативная память;
  • I/O - Устройства ввода/вывода;

Интерфейс — набор правил и средств взаимодействия двух систем. Иными словами способ взаимодействия.

Kernel space — адресное пространство ядра ОС, в котором процессы имеют привилегированный доступ к ресурсам компьютера и другим процессам.

User space — адресное пространство, отведённое для пользовательских процессов (приложений), то есть не имеющих привилегированный доступ к ресурсам.

Как операционная система загружается в компьютер?

Процесс загрузки операционной системы и вообще компьютера имеет несколько этапов, основные из которых:

  1. Запуск компьютера – на процессор подаётся напряжение и его элекрические компоненты начинают работу.
  2. Процессор начинает исполнять инструкции с фиксированного, аппаратно зашитого в него адреса.
  3. По этому адресу находится специальная программа POSTPower On Self Test. Которая проверяет работоспособность основных компонентов вычислительной системы.
  4. Далее, управление передаётся BIOS’y — Basic Input Output System (Базовая система ввода-вывода), которая инициализирует основные устройства ввода-вывода: загрузочные устройства (раличные хранители информации: HDD, SSD, Flash и так далее), клавиатура, монитор и прочее.
  5. BIOS обращается к загрузочному устройству и читает первый блок данных, на котором должен находиться загрузчик. Загружает его в память и передаёт ему управление.
  6. Загрузчик загружает в память и инициализирует основные компоненты операционной системы и передаёт ей управление.
  7. Операционная система запускает таймер, который будет возвращать управление операционной системе каждый, заранее установленный разработчиками ОС, квант времени. Это делается для реализация Scheduler’a - планировщика, чтобы ОС могла управлять и контролировать процессы.
  8. Операционная система создаёт первый процесс-пользователя и дальше от него начинают множится другие процессы.

Что делает ядро ОС?

Ядро ОС – центральная часть операционной системы. По сути, это и есть ОС.

Внимание

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

  • Обрабывает запросы приложений
    • системные вызовы (программные прерывания)
  • Обрабывает запросы оборудования
    • прерывания
  • Обрабатывает исключительные ситуации
    • Разного рода ошибки
  • Обеспечивает диспетчеризацию процессов (scheduling)
    • реализация многопользовательского режима доступа к ресурсам
      • время работы процессора делится на фрагменты и они распределяются по процессам

Примечание

Процессорное время измеряется в тиках или секундах. Часто бывает полезно измерение процессорного времени в процентах от мощности процессора, которое называется загрузкой процессора.

Вывод программы top

Вывод программы top. Процессорное время каждого процесса (task) указано в колонке «TIME+», «CPU%» - загружаемость процессора относительно его «мощности».

Прерывания

Примечание

Эта часть больше относится непосредственно к аппаратной части, но этот механизм стоит освятить, так как именно это основной аппаратный механизм реализации ОС.

Прерывание – сигнал остановки последовательного выполнения программы, для обработки запроса или реакции на событие.

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

Инициализация данной таблицы первично осуществялется BIOS’ом в соответствии с архитектурой процессора. После, её инициализирует операционная система для дополнения этой таблицы какими-либо своими прерываниями.

Виды и примеры прерываний:
  • Аппаратные прерывания – с помощью специального контроллера прерываний.
    • Нажатие на кнопку
    • Заполнение памяти сетевой карты
    • И тд.
  • Программные прерывания (системные вызовы) – вызывается самой программой для вызова того или иного прерывания.
    • Открытие/закрытие файла
  • Прерывания таймера – для реализации планировщика ОС
  • Исключение
    • Разного рода ошибки

Как приложения взаимодействуют с ОС?

Взаимодействие процессов с ОС осуществляется с помощью системных вызовов.

Примечание

Механизм системных вызовов — это интерфейс, который предоставляет ядро ОС (kernel space) пользовательским процессам (user space).

Системный вызов – программное прерывание, обращение пользовательского процесса к ядру операционной системы для выполнения какой-либо операции.

Например, чтобы выполнить обычное действие, с точки зрения прикладного программиста, – вывод строки в консоль, необходимо загрузить исполнимый код в оперативную память и передать его процессору. С помощью системных вызовов, запускающий процесс (уже запущенный процесс, из которого вызывается новый процесс — одни процессы порождают другие) обращается к соответствующим сервисам ОС и передаёт им управление для выполнения этих функций.

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

Схема организации ОС расширяется добавлением интерфейса для взаимодействия приложений с ядром ОС — механизмом системных вызовов:

Рис 4. Интерфейс системных вызовов

Рис 4. Интерфейс системных вызовов

Как оборудование взаимодействует с ОС?

Оборудование взаимодействует с ОС с помощью аппаратных прерываний. И одна из функций ОС — абстрагирование оборудования.

Что это значит?

У каждого оборудования есть свой фиксированный интерфейс. Например, операции с флешкой, жестким диском, сетевой платой и многими другими будут похожи по своему типу - «записать/считать данные». Но у каждого устройства для этого, тем не менее, будет свой особенный и отличный от других интерфейс. То есть эти однотипные действия нужно будет выполнять для разных устройств по разному.

ОС должка выполнять одни и те же операции над разными типами устройств. И чтобы она выполняла их однообразно — нужно чтобы был общий интерфейс. Реализацией этого общего интерфейса занимаются специальные программы - драйверы устройств. То есть, ОС обращается к драйверам устройств используя однотипные команды «отправить команду/считать/записать», а драйвера уже превращает эти команды в то, что понимает конкретное устройство.

Схема организации ОС расширяется добавлением интерфейса взаимодействия ОС и оборудования - специальные программы «драйвера»:

Рис 5. Интерфейс драйверов

Рис 5. Интерфейс драйверов

Сервисы ОС

Функции ОС заключены в её сервисах (модулях). Реализация организации которых зависит от архитектуры ядра. Рассмотрим на примере монолитного ядра:

Рис 6. Основные компоненты ОС

Рис 6. Основные компоненты ОС

Основные

  • Управление процессами (Process scheduler - планировщик)
    • Запуск (помещение на процессор, выделение процессорного времени)
    • Приостановка (заморозка)
    • Завершение
    • Изменение приоритета

Примечание

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

  • Межпроцессное взаимодействие (IPC - Inter Process Communication)
    • Общая память для нескольких процессов (shared memory)
    • Способы обмена данными через те или иные механизмы (file, pipe, signals)
    • Сетевое взаимодействие
    • Механизмы предотвращения коллизий и синхронизации (семафоры, мьютексы)
  • Управление памятью (Memory manager)
    • Динамическое выделение памяти (Memory allocation)
    • Создание иллюзии уникальности адресного пространства для каждого процесса
    • Механизм виртуальной памяти

Дополнительные

  • Файловая система (File system)
    • Файлы и их содержимое
    • Каталоги и директории
  • Доступ к оборудованию и управление им
    • Прерывания
    • Драйвера
  • Модель безопасности
    • Пользователи («юзеры») и их группы
    • Права доступа
  • Разное
    • Интерфейс ввода-вывода (I/O Interface)
    • Сетевой интерфейс (Network Interface)

Основные абстракции

Процесс

Процесс — совокупность инструкций и данных, что находятся в оперативной памяти и обрабатываются процессором. Другими словами - исполнение программы в целом (не путать с потоком исполнения).

Примечание

Компьютерная программа сама по себе — лишь пассивная последовательность инструкций. В то время как процесс — непосредственное выполнение этих инструкций.

В рамках ОС, это абстракция, которая предоставляет иллюзию персональной машины. То есть то, что данный исполнимый код полностью владеет всеми вычислительными ресурсами машины.

Состояние (контекст) процесса

С внешней стороны, процесс можно описать следующим:
  • Состояние
    • Состояние памяти
    • Содержимое регистров процессора
  • Адрестное пространство — у каждого процесса своё.
  • Состояние исполнения — то, исполняется ли этот процесс на процессоре в данный момент или ожидает чего-либо.
  • CPU - величина использовния процессорного времени.

Изнутри, процесс можно условно разделена на четыре части: Stack, Heap (кучу), Text (код) и данные (Data).

Рис 7. Сегменты памяти процесса

Рис 7. Сегменты памяти процесса

Состояния исполнения

Когда процесс выполняется, он проходит через разные состояния. Эти этапы могут различаться в разных операционных системах.

Общая картина выглядит так:

Рис 8. Состояния исполнения процесса

Рис 8. Состояния исполнения процесса

Примечание

  • Новый: начальное состояние при создании процесса.
  • Готов: процесс ожидает исполнения на процессоре. В течение работы процессор может переключаться между процессами, переводя одни в режим готовности, другие – в режим исполнения.
  • Исполнение: непосредственное выполнение инструкций на процессоре.
  • Ожидает: процесс переходит в состояние ожидания. Например, ждёт ввода данных или получения доступа к файлу.
  • Завершен: как только процесс завершится, он перейдёт в это состояние и будет ожидать удаления.

Информация о процессе

Вся информация о процессе содержится в специальной структуре данных, поддерживаемой операционной системой для каждого процесса – PCB (Process Control Block) - Блок управления процессов.

Рис 9. Process Control Block

Рис 9. Process Control Block

Примечание

  • Process ID: идентификатор каждого из процессов в ОС.
  • State: текущее состояние процесса.
  • Privileges: разрешения доступа к системным ресурсам.
  • Pointer: указатель на родительский процесс.
  • Priority: приоритет процесса и другая информация, которая требуется для планирования процесса.
  • Program Counter: указатель на адрес следующей команды, которая должна быть выполнена.
  • CPU registers: регистры процессора, необходимые для состояния исполнения.
  • Accounting Information: уровень нагрузки на процессор, статистика и другие данные.
  • I/O Information: список ресурсов, использующих чтение и запись.

Информацию о процессах в целом, ОС хранит в специальной таблице процессов.

Поток

Процесс может делиться на потоки (threads). Они обеспечивают параллелизм, то есть одновременное исполнение нескольких потоков инструкций, на уровне программы.

Поток выполнения (нить, thread) — последовательность исполнения инструкций. Ход исполнения программы**.

Процесс является контейнером ресурсов (адресное пространство, процессорное время и тд), а поток – последовательность инструкций, которые исполняются внутри этого контейнера.

Примечание

Реализация потоков выполнения и процессов в разных операционных системах отличается друг от друга, но в большинстве случаев поток выполнения находится внутри процесса.

Рис 10. Многопоточный процесс

Рис 10. Многопоточный процесс

Потоки, существующие в рамках одного процесса, в его адресном пространстве, могут совместно использовать ресурсы процесса, например такие как память или файл. Тогда как процессы не разделяют этих ресурсов, так как каждый существует в своём адресном пространстве.

Также поток называют легковесный процесс.

Сегодня потоки широко применяются в работе серверов и многопроцессорных устройств с общей памятью.

Рассмотрим на примере утилиты htop.

Рис 11. Вывод утилиты мониторинга процессов htop

Рис 11. Вывод утилиты мониторинга процессов htop

Примечание

PID — Process ID; Уникальное число идентификатор для каждого процесса

TGID — Tread Group ID; Индентификатор группы потоков

На скриншоте, процесс 2881 имеет множество потоков, отношение которых к нему можно определить по тому, что TGID у этих потоков имеет значение PIDа этого процесса - 2881. Таким образом, один процесс разбивается на множество потоков, в которых инструкции исполняются параллельно.

Чем хороши потоки

  • Они минимизируют время переключения контекста (процессора).
  • Их использование обеспечивает параллелизм процесса.
  • Они эффективно общаются между собой.
  • Потоки позволяют использовать многопроцессорные архитектуры в большем масштабе.

Файл

Это очень широкое и многогранное понятие. Но если выделить наиболее общее, то получится, что файл — это универсальный системный интерфейс для обращения к тем или иным данным.

А файловая система — это система имён. То есть возможность выделять те или иные объекты данных и присваивать им имена, а также выделять иерархию.

По другому, файл и файловую систему можно также представить как структуру данных и связи между этими структурами.

Реализация многозадачности

Осуществляется при помощи следующих механизмов:

  • Прерывание таймера
    • когда при запуске, ОС программирует таймер на то, чтобы он каждый квант времени передавал управление ОС.
  • Переключение контекста
    • сохранение состояния исполнения (регистров) процесса и установка на процессор контекста другого процесса.
  • План блокировок, при наличии нескольких CPU
  • Освобождение ресурсов при завершении процесса

Переключение контекста

Контекст процесса — это состояние регистров, при его выполнении на процессоре.

Следовательно, переключение контекста — это смена контекста одного процесса, на контекст другого, без потери данных сменяемого процесса - то есть, чтобы его потом можно было восстановить с того момента, где он был переключён.

Примечание

Например, у нас на процессоре в данный момент времени выполняется «процесс 1» - в регистрах хранятся данные, которые относятся к этому процессу.

Но происходит прерывание и «процесс 1» снимается с выполнения на процессоре, чтобы вместо него выполнялся «процесс 2». Следовательно, нужно заполнить регистры уже теми данными, что относятся к «процессу 2».

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

При переключений контекста возникает три важных вопроса:
  1. Как?
  2. Когда?
  3. Между кем и кем?

Как?

  1. Значения регистров процесса записываются в Stack этого же процесса в оперативной памяти. Таким образом, процесс в своей памяти хранит свой же контекст.
  2. Контекст планировщика появляется на процессоре, выполняет анализ имеющихся процессов.
  3. Переключает процессор на контекст уже другого, нового процесса.

В целом, смена контекста происходит между состояниями «Готов», «Ожидает» и «Исполняется».

Состояния исполнения процесса

Критические секции и блокировки

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

Возникают, так называемые, критические секции – участки исполняемого кода программы, в которых производится доступ к общему ресурсу (данным или устройству), который не должен быть одновременно использован более чем одним потоком выполнения.

Рис 12. Критические секции в потоках процесса

Рис 12. Критические секции в потоках процесса

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

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

Примечание

Все эти механизмы обеспечиваются операционной системой

Чтобы лучше это понять, можно обратиться к аналогии с туалетом — им может пользоваться только один человек. Если другой хочет им воспользоваться, то ему нужно дождаться когда его освободит уже им пользующийся.

Deadlock - взаимная блокировка

Из-за блокировки, захвата ресурса может возникнуть другая проблема: Deadlock - взаимная блокировка.

Рис 13. Аналогия пробки на перекрёстке с Deadlock

Рис 13. Аналогия пробки на перекрёстке с Deadlock

Deadlock — ситуация, при которой несколько потоков находятся в состоянии ожидания ресурсов, занятых друг другом, и ни один из них не может продолжать свое выполнение.

Пример Deadlock’a на псевдокоде

Шаг Поток 1 Поток 2
0 Хочет захватить A и B, начинает с A Хочет захватить A и B, начинает с B
1 lock(A) — Захват А lock(B) — Захват B
2 lock(B) — Ожидает освобождения ресурса B lock(A) — Ожидает освобождения ресурса A
DEADLOCK –> Далее код не выполнится, так как произошел Deadlock в коде выше
n unlock(A) — освобждение A unlock(B) — освобждение B
n+1 unlock(B) — освобждение B unlock(A) — освобждение A

Схематично, Deadlock можно изобразить так:

Рис 14. Deadlock

Рис 14. Deadlock

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

Адреса и управление памятью

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

Существует два вида адресов:
  • Физический адрес – непосредственно адрес внутри микросхемы памяти, который передаётся по шине памяти.
  • Логический адрес – тот адрес, которым оперирует процесс.

Чтобы отобразить логический адрес в физический, существует специальный аппаратный механизм.

В соответствии с этим, процессор может работать в двух режимах:
  1. Реальный режим
  2. Защищенный режим

Итог

Начав с базовой архитектуры и небольшой истории развития компьютера, мы разобрали причины появления такого комплекса программ как операционная система и выделили главную её цель – обеспечение согласованного доступа к ресурсам компьютера множеству пользователям этих ресурсов, а также управление как самими ресурсами, так и пользователями.

Основные механизмы (сервисы)

Рассмотрели основные механизмы реализации этой цели: Scheduler (планировщик), Inter Process Communication (межпроцессное взаимодействие), Memory manager (управление памятью) и другие.

Абстракции

Ряд абстракций, которые вводит ОС: Process (процесс), Thread (поток исполнения), File (файл).

Заключение

Ух, и вот наконец-то я закончил писать этот материал. Надеюсь, вам было интересно и полезно.

Если вы хотите как-то дополнить материал, дать критику по его содержанию или структуре – пожалуйста, пишите в Issue данного репозитория поднимая ту или иную тему для обсуждения и доработки.

Также, вы можете сделать Fork данного репозитория и после внести свои дополнения с помощью Pull Request. Спасибо за внимание!