Что не программист усвоил из бесплатного курса от Хекслета «Операционные системы»

Статья написана студентом Хекслета. Мнение автора может не совпадать с позицией редакции
Читать в полной версии →

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

Основные понятия

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

Операционная система (ОС) — это интерфейс между компьютером и человеком.

Интерфейс – это «посредник», «переводчик», который обеспечивает взаимопонимание сторон: железо-программа-человек (например: жёсткий диск, Total Commander и Олег).

У каждой из этих трёх частей свой язык, а интерфейс – это способ общения частей между собой.

Пользователь – это агент: программа или человек.

Программа – это набор инструкций для процесса.

Процесс – фактическое исполнение инструкций программы, то есть работающая программа, instance of a program.

Тред (thread) – мельчайшая единица процесса. Процесс состоит из тредов.

Задача – единица работы, которая включает в себя один или несколько процессов или тредов.

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


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

Основные задачи ОС – это регулировать процессы. Она делает следующее:

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

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

Но здесь есть оговорки и нужно много уточнять про принципы распределения ресурсов. Там на инженерном уровне встают сложные вопросы: кому (какому процессу) отдавать приоритет – может, этот новый процесс более важный и ему действительно надо передать задействованную другим процессом память, чтобы вся система не упала? Как долго он должен исполняться? Как избежать ситуации, когда всеми ресурсами пользуются самые приоритетные процессы, а остальные «голодают» (так называемое «ресурсное голодание»)?

Про память поговорим чуть подробнее позже по тексту.

Процесс

Жизнь процесса проходит в два этапа: создание и уничтожение. В своём жизненном цикле процесс может проходить такие состояния:

Когда процесс находится в состоянии «готов», «запущен» или «заблокирован», он занимает оперативную память (RAM). Состояние «приостановлен» означает, что ОС перенесла процесс во вторичную память – ведь ресурс RAM нужен другим процессам и при этом он ограничен. Вторичная память – это HDD или SSD или другое не-RAM хранилище. Такой перенос происходит, когда процесс долго простаивал в очереди, то есть пребывал в состоянии «заблокирован». Возможные причины переноса процесса из оперативной памяти: долго шёл ответ от устройства ввода-вывода (input-output, I/O), в том числе ожидание, пока человек нажмёт на кнопку «ОК».

Заблокированные (ожидающие) процессы ждут разного: какие-то процессы ждут ответа от пользователя, другие от видеокарты, третьи от жёсткого диска. Для оптимизации работы компьютера операционная система разносит процессы по смысловым очередям:

Процессор

Всё, что происходит на компьютере, это расчёты, производимые процессором.

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

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

Проблема в том, что все остальные элементы компьютера медленнее процессора. Процессор – это как Флэш / Ртуть / Белка из «Лесной Братвы», а всё остальное в компьютере (и уж тем более человек) – это ленивец Блиц из «Зверополиса». Так как процесс – это набор инструкций и I/O постоянно обмениваются данными с CPU, а процессор справляется с задачами чрезвычайно быстро, в итоге CPU может простаивать в ожидании следующего ответа от исполняющегося сейчас процесса.

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

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

Note: на современных многопроцессорных и многоядерных системах процессы действительно исполняются параллельно – каждое ядро обрабатывает свой процесс.

Не перепутать ядра:

Внутри каждого процесса существуют треды (thread – поток, нить). Грубо говоря, это такие мини-«процессы», которые позволяют выполнять несколько инструкций одного процесса. Каждому треду операционная система предоставляет доступ к ресурсам: время работы CPU, память, доступ к I/O и к другим ресурсам.

Важно уточнить, что тред – это отдельная сущность, его нельзя назвать «процессом» в прямом смысле этого слова.

Основные архитектуры процессоров: SISD, SIMD, MISD, MIMD.

Память

Результат вычислений и процесс (исполняемый набор инструкций от программы) хранятся в оперативной памяти (RAM).

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

Представьте, что выполненный процесс – это убранная с полки книга. Вот только процессы / книги убираются не одна за другой, а из разных мест (убрали книги №1, 3, 4 и 9) и в результате на книжной полке появляются дыры, ряд книг становится похож на решето. Если мы хотим поставить толстый словарь Ожегова на пустое место, откуда недавно убрали тоненькую брошюрку, то мы не сможем этого сделать и это место будет «ждать» подходящей книги.

Чтобы избежать таких ситуаций ОС использует логическую память. Логическая память – это кусок памяти, которую ОС «показывает» программе, как бы убеждая её: у тебя бесконечно много памяти, используй сколько тебе надо. Физически на нашей полке остаётся всё то же решето или места вообще не остаётся. Но для процесса создаётся виртуальное пространство памяти, где вся память выделена исключительно для него и ему не надо заботиться о том, чтобы найти свободное место и не надо думать о действительно доступном объёме. Это как если бы вы пришли в библиотеку и вернули книгу или, наоборот, захотели взять её. Библиотекарь сам поставит эту книгу на нужную полку или принесёт вам книгу с нужной полки, а вам не надо беспокоиться об их расстановке. И даже если все полки библиотеки забиты, это всё равно не ваша забота.

Очень упрощённый пример реализации:

  1. У нас уже заняты 14 из 16 ГБ памяти (RAM).
  2. Потом ОС выделяет процессу ‘A’ ещё 2 ГБ – теперь заняты 16 из 16 ГБ. Но сейчас процесс ‘A’ использует только 0.5 ГБ, а процессу ‘B’ нужны 1.5 ГБ.
  3. Тогда ОС выделяет процессу ‘B’ эти 1.5 ГБ из RAM, а зарезервированные 1.5. ГБ за процессом ‘A’, но пока не используемые, отправляет на вторичное хранилище.

Это выглядит так, словно бы ОС выделила 17.5 ГБ из 16 ГБ. Такое возможно благодаря виртуальной (логической) памяти.

Планирование выполнения задач

Процесс пребывает в таких состояниях:

Для наглядности приведу скриншот из видеоурока курса.

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

Чтобы ОС работала быстро и программы не тормозили, разработчики ОС применяют сочетание алгоритмов.

Ввод-вывод (I/O)

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

Так как эти устройства медленные, а процессор не должен простаивать, ожидая от них ответа, на общую с CPU и RAM шину инженеры установили доп. устройство – упрощённый процессор, выполняющий роль «менеджера» или «посредника». Такое устройство называют DMA (Direct Memory Access). Представьте, что процессор – это владелец бизнеса, а DMA – это его секретарь, который отвечает на звонки, назначает встречи. DMA приносит процессору работу на блюдечке: I/O соизволило донести свои данные, DMA их получил и тут же сообщил процессору: «вот процесс, можно производить расчёты».

Алгоритм выглядит так:

  1. Модуль DMA получает от процессора право на проведение операции.
  2. Модуль DMA переносит информацию из памяти / в память.
  3. Когда информация перенесена, модуль DMA отправляет сигнал прерывания процессору и тогда процессор обрабатывает поступившую инфу.

I/O по-прежнему всё ещё медленные. Проблемы:

Такая операция называется буферизация.

О чём я не написал в статье из того, о чём было сказано в курсе?

Я не ставил целью переписать курс. Целью статьи было уложить в своей голове то, что более-менее понял и восполнить пробелы в этих «понятных» частях. Всё, что мне совсем непонятно, я отложил на будущее.

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

Если вы заметили ошибку или хотите что-то уточнить, пожалуйста, напишите об этом в ЛС или в комментариях.