Дизайн операционной системы: минимальные сведения об устройстве

Сергій Бондаренко

Как устроены современные операционные системы? Почему Linux и UNIX прослыли стабильными, а MS-DOS работала медленно? Почему часто падает Windows, и какая идея лежит в дизайне гибридной macOS? Как в целом ОС работают с памятью и управляют процессами? О некоторых особенностях устройства современных ОС и их реализации — читайте в нашем новом материале.

Содержание:
1. Что такое интерфейс
2. Как работает ОС
3. Прерывания, управление процессами
4. Ядро операционной системы
5. Реализация ОС
6. Мультипоточность
Заключение

1. Что такое интерфейс

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

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

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

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

2. Как работает ОС

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

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

Сердце компьютера — процессор. Процессор состоит из двух блоков — арифметико-логического устройства и управляющего автомата. Также процессор содержит небольшую быструю внутреннюю память. Арифметико-логическое устройство занимается простыми вычислениями: складывает, вычитает и производит другие действия над числами. Управляющий автомат сообщает памяти компьютера, арифметическому и логическому устройству, а также устройствам ввода и вывода, как реагировать на инструкции, которые были отправлены процессору.

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

Системная шина состоит из нескольких уровней, каждый из которых передает свой тип данных: уровень адресов, уровень данных и уровень команд.

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

Функционально процессор выполняет всего три действия:

  1. считывает из памяти инструкции (из регистра инструкций).
  2. выполняет инструкцию.
  3. возвращает в память результат.

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

3. Прерывания, управление процессами

Самые ранние модели электронно-вычислительных устройств выглядели как огромные шкафы, с лампами и другой, примитивной по сегодняшним меркам, электронной начинкой. Человек записывал в память этой машины инструкции, а затем через некоторое время приходил и считывал из памяти результаты вычислений.

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

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

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

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

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

4. Ядро операционной системы

Когда разговор заходит о структуре операционной системы, то самое основное — ядро. Существует два основных направления в проектировании ядер ОС — монолитное ядро и микроядро (а также множество вариаций и комбинаций этих решений).

Монолитное ядро подразумевает, что вся операционная система — это одна большая программа, которая имеет максимальный доступ к ресурсам компьютера. В нее стараются поместить как можно большее число полезных функций. Грань между ОС и не-ОС очень абстрактна и зависит от решений, принятых дизайнерами ОС. Например, драйверы каких-то устройств или графический интерфейс для одних ОС будет являться частью системы, а для других ОС они могут являться просто пользовательскими приложениями.

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

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

В операционной системе всегда есть процесс, с которым взаимодействует пользователь. Например, при старте системы происходит запуск процесса графического или текстового интерфейса для ввода пароля. После правильного ввода пароля создается следующий процесс, например, интерпретатор командной строки bash и т.д.

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

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

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

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

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

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

Структура данных, которая используется ОС для представления процесса называется Process Control Block. При запуске нового процесса ОС создает эту структуру данных.

Процессы обычно создаются самой ОС, но часто процессы порождают новые дочерние процессы.

Для прекращения процесса необходимо одно из условий:

  1. сигнал операционной системы HALT.
  2. действие пользователя.
  3. ошибка.
  4. завершение родительского процесса.

Запущенные в ОС процессы организованы в очередь. При этом процессы, которые находятся в состоянии ожидания отклика от устройств ввода-вывода, помещать в такую очередь не имеет смысла. Когда подойдет их время, они все еще будут находиться в состоянии ожидания и зависеть от аппаратной части. Для этих процессов используется отдельное состояние, при котором процесс заблокирован. Это состояние может использоваться, например, когда идет ожидание события, скажем, на экране показывается «нажмите на кнопку ОК».

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

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

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

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

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

При переключении процесса происходит следующий порядок действий. Сохраняется состояние процесса (регистры). Затем обновляется контрольный блок процесса, который запущен в данный момент. Контрольный блок процесса переносится в соответствующую очередь (готов, заблокирован, приостановлен). На основании очереди готовых к запуску процессов выбирается другой процесс для выполнения Затем обновляется контрольный блок процесса, на который необходимо переключиться, обновляются структуры данных управления памятью и восстанавливается состояние процесса.

5. Реализация ОС

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

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

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

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

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

6. Мультипоточность

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

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

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

Смысл использования тредов состоит в более эффективном использовании ресурсов. Создание нового треда занимает меньше времени, чем создание нового процесса. Отдельные треды могут общаться друг с другом в обход ядра, что также повышает скорость выполнения задач. Решение ОС по поводу процесса оказывает влияние на все потоки этого процесса (например, приостановка процесса означает приостановку всех потоков, завершение процесса — завершение потоков). Треды можно реализовывать на уровне ядра (kernel-level threads) или на уровне пользователя (user-level threads).

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

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

Заключение

Мы разобрались с процессами и тредами операционной системы, однако за кадром осталось много других интересных особенностей архитектуры современных ОС.

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

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023