Learning Platform
Глоссарий Troubleshooting
Урок 03.01 · 18 мин
Начальный
OSHistoryAbstractionsMultitasking

Зачем нужна ОС — что было до и что она даёт

Когда вы пишете open("data.txt") — вы не задумываетесь, на каком диске лежит файл, какие там сектора, как работает контроллер SSD, и как несколько программ одновременно читают разные файлы без конфликтов. Всё это берёт на себя операционная система. Она — слой между вашим кодом и железом, который превращает «куча шестерёнок» в «понятный интерфейс».

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

NOTE

С этого урока мы спускаемся на технический слой — начинаем заглядывать «под капот». Дальше будут появляться команды в терминале и новые слова. Это нормально и так задумано: каждый новый термин мы объясняем на месте, простыми словами и с примером. Если вы ещё ни разу не открывали терминал и не уверены, что такое «команда», «файл» или «путь» — сначала пройдите вводный курс computing-basics: он за руку проводит через установку и первые шаги в командной строке на Mac, Windows (WSL2) и Linux. После него этот курс будет ощущаться заметно проще.


Жизнь без ОС: 1940-50е годы

Первые компьютеры — ENIAC (1945), UNIVAC (1951) — работали без ОС. Программист сам:

  • Грузил программу в память (бумажная лента, перфокарты, иногда прямо проводами!).
  • Запускал её, нажимая кнопки на пульте.
  • Если что-то падало — разбирал ошибку через лампочки и переключатели.
  • Программа имела полный доступ ко всему железу. Хочешь записать в любую ячейку памяти — пиши. Хочешь подвинуть головку диска — двигай.
Эволюция отношения программа-железо
1945-55Прямой доступ программы к железу. Одна программа в момент времени. Программист бронирует машину на N часов. Никакой защиты, никакой многозадачности
1955-65Batch systems: программы запускаются последовательно из очереди. Появляются библиотеки кода (I/O routines), которые становятся прото-ОС. Все программы делят память и могут друг друга испортить
1965-80Multics, UNIX, VMS: первые настоящие ОС с многозадачностью, защитой памяти, файловой системой, пользователями. Все ОС сегодня -- наследники этой эпохи
1980-2000PC-эра: DOS (без защиты!), Windows 3.x/9x (плохо защищённые), Linux (полноценный UNIX на PC), macOS, BSD. Кооперативная и preemptive многозадачность
2000-сейчасСовременная эра: десятки cores, виртуализация (контейнеры, VM), мобильные ОС (Android, iOS), embedded RTOS. ОС стала очень сложной системой

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

Появилась идея пакетной обработки (batch processing): кладёте стопку перфокарт в очередь, оператор скармливает их машине одну за другой. Появились библиотеки кода (например, для чтения карт или вывода на принтер) — это и были первые прото-ОС. IBM System/360 (1964) запустила OS/360 — это уже была настоящая ОС, хоть и без многозадачности.


Прорыв 1965: Multics и идея многозадачности

В 1965 году в MIT начался проект Multics (Multiplexed Information and Computing Service) — амбициозная ОС, которая должна была обслуживать сотни пользователей одновременно с одного мощного компьютера (как электростанция, поставляющая компьютер-время вместо электричества).

Ключевые идеи Multics, которые сейчас есть в любой ОС:

  1. Многозадачность. Несколько программ выполняются «одновременно» (на самом деле — быстро переключаясь). Пользователь не ждёт окончания одной программы, чтобы запустить вторую.
  2. Виртуальная память. Каждой программе кажется, что у неё свой компьютер с собственной памятью.
  3. Защита. Одна программа не может испортить другую или ядро.
  4. Иерархическая файловая система. Директории внутри директорий, у файлов есть владелец и права.
  5. Пользователи и группы. Несколько людей делят одну машину, но не видят файлы друг друга без разрешения.

Multics был сложным и амбициозным, но AT&T вышла из проекта. Двое разработчиков — Кен Томпсон и Деннис Ритчи — ушли работать над более простой версией. Так в 1969 году в Bell Labs появился UNIX. Из UNIX выросли все современные мейнстрим-ОС: Linux, macOS, FreeBSD, Android. Windows NT (на котором стоит Windows сегодня) тоже сильно вдохновлялся UNIX-идеями, хоть и пошёл своим путём.


Что делает ОС: пять главных функций

Современная ОС решает пять групп задач. Знание этих задач — скелет курса.

Пять функций операционной системы
1. Process MgmtУправление процессами: запуск программ, переключение между ними, завершение, межпроцессное взаимодействие. Без этого -- одна программа в момент времени
2. Memory MgmtУправление памятью: виртуальная память, page tables, swap, OOM. Без этого -- программы видят друг друга в памяти, всё ломается
3. File SystemФайловая система: открытие, чтение, запись файлов. Директории, имена, права. Без этого -- программа работает с сырыми блоками диска
4. Devices/IOУправление устройствами: драйверы для дисков, сети, видео, USB. Программа работает с абстракцией 'файл' вместо общения с контроллером по PCI
5. SecurityБезопасность: пользователи, права, изоляция процессов, capabilities. Одна программа не должна читать память другой или удалять чужие файлы

Разберём каждую функцию подробнее.

1. Управление процессами

Без ОС: одна программа в момент времени. С ОС: десятки тысяч процессов «одновременно». На вашем ноутбуке прямо сейчас запущено 200+ процессов:

# Сколько процессов прямо сейчас?
ps -e | wc -l
# Что-то вроде 234

# А потоков? (каждый процесс может иметь несколько потоков)
ps -eLf | wc -l
# Что-то вроде 1542 (часто в 5-10 раз больше процессов)

Все они хотят CPU. Но CPU у вас, например, 8 ядер — то есть физически одновременно может работать максимум 8 потоков. ОС создаёт иллюзию многозадачности: переключает потоки на ядрах быстрее, чем человек заметит (типично 100-1000 раз в секунду). Программисту не нужно думать об этом — он пишет код, как будто его процесс единственный.

2. Управление памятью

У вас в системе, скажем, 16 GB RAM. Запущено 200 процессов. Если бы каждый имел доступ ко всей памяти напрямую — они бы перетёрли друг друга через 5 секунд.

ОС создаёт иллюзию: каждый процесс думает, что у него свой компьютер с 128 TB виртуальной памяти (на 64-bit системах). Реально страницы физической памяти раздаются по требованию. Когда RAM кончается — редко используемые страницы вытесняются в swap (на диск). Когда процессу нужна страница, которая в swap — ОС подкачивает обратно.

Программисту не нужно знать про эти страницы. Он пишет malloc(1_000_000) — получает указатель. Внутри — сложная машинерия virtual memory + paging + MMU.

3. Файловая система

Без ОС: файл — это байты на диске по определённому смещению. С ОС: файл — это имя в иерархии (/home/user/data.txt), у него есть метаданные (owner, permissions, mtime), его можно открыть как поток (read/write), и под капотом ОС переводит это в чтение блоков с физического диска.

ОС абстрагирует множество разных файловых систем (ext4, xfs, btrfs, ntfs, fat32, tmpfs) под одним интерфейсом VFS (Virtual File System). Программа делает open("/path/file") — VFS определяет, к какой ФС это относится, и вызывает соответствующий драйвер.

FHS: структура файловой системы Linux

4. Управление устройствами

Без ОС: чтобы прочитать данные с диска, программа должна общаться с контроллером по PCI: установить регистры команд, ждать прерывания, читать буфер. Каждая модель диска — свой протокол.

С ОС: программа делает read(fd, buf, size) — ОС переводит это в команды для соответствующего драйвера. Драйвер знает специфику железа. Программе всё равно, что под капотом NVMe SSD, SATA HDD, RAM disk или сетевой файл NFS.

То же со всем: сетевая карта, USB, графика, аудио, периферия. Десятки тысяч моделей железа — единый интерфейс.

5. Безопасность и изоляция

Пользователи и группы: /etc/passwd, /etc/shadow

ОС следит, чтобы:

  • Один процесс не читал память другого без разрешения (изоляция).
  • Один пользователь не читал/писал файлы другого без прав (permissions).
  • Программа не получила доступ к ресурсам, которые ей не разрешены (capabilities).
  • Если процесс делает что-то опасное (хочет писать в чужую память) — он крашится через segmentation fault, не унося с собой всю систему.

Без этого — браузер с уязвимостью читал бы пароли из памяти банковского клиента. ОС физически препятствует этому через виртуальную память и privilege levels.


Главный концепт: ОС как абстракция

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

Сырое железо vs ОС-абстракции
Raw: PCI registersБез ОС: программа пишет в регистры контроллера диска, инициирует DMA, ждёт прерывание. Знает модель чипа, regions памяти. Меняешь железо -- переписываешь программу
OS: open/read/writeС ОС: open('/path/file'), read(fd, buf, size). Один интерфейс на любой носитель: SSD, HDD, USB-флешка, сетевой диск NFS. Программа переносима
Raw: physical addressesБез ОС: программа знает физические адреса памяти. Если её данные с адреса 0x1000 -- они там и есть. Две программы не уживаются
OS: virtual memoryС ОС: программа работает с виртуальными адресами. Указатель в одной программе и тот же указатель в другой -- разные физические страницы. Изоляция
Raw: ethernet framesБез ОС: программа собирает Ethernet frame, выбирает MAC-адрес назначения, обрабатывает ACK по каналу. Для каждой сетевой карты -- своя реализация
OS: socketsС ОС: socket(), connect(), send(), recv(). Один интерфейс на TCP/UDP/Unix/Bluetooth. Программа не знает, какая сетевая карта стоит

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


Многозадачность: timeline переключений

Давайте конкретно посмотрим, как ОС создаёт иллюзию одновременной работы. Допустим, у вас одно ядро CPU и три процесса: vim, chrome, python. Каждый хочет выполняться.

Timeline планирования: один CPU, три процесса
t=0ms: vimvim получает CPU. Запускается из ready состояния в running. Работает 10ms
t=10ms: switchИстёк квант времени (time slice). ОС вызывает scheduler, сохраняет состояние vim (регистры, стек) в его process control block
t=10ms: chromeChrome получает CPU. Запускается с того места, где остановился в прошлый раз -- ОС восстановила его регистры
t=20ms: switchОпять переключение. Сохраняем chrome, восстанавливаем python
t=20ms: pythonPython работает 10ms. Затем -- снова vim. Цикл повторяется
...За одну секунду на одном ядре происходит 100-1000 переключений между всеми процессами в системе. Пользователь видит 'плавную' работу одновременно нескольких программ

Это preemptive multitasking — ОС сама решает, когда переключить процесс. На каждом переключении — сохраняет состояние одного и восстанавливает другое (это называется context switch). Контекстный переключатель занимает порядка 1-10 микросекунд, поэтому overhead заметен только при очень частых переключениях.

Альтернатива — cooperative multitasking: процесс сам отдаёт CPU, когда «хочет» (через явный yield). Так работала Windows 3.1 и старые macOS. Проблема: если процесс зациклился и не отдаёт CPU — система зависает. Все современные ОС используют preemptive.


А зачем мне это, если я пишу Python?

Резонный вопрос. Python отдалён от системы тремя слоями: ваш код -> Python interpreter -> libc -> ОС. Зачем знать про ОС?

Ответ 1: производительность. Когда ваш скрипт медленный, нужно понимать, где он застрял: CPU-bound (нагрузка на ядро) или I/O-bound (ждёт диск/сеть). Это две принципиально разные оптимизации. CPU-bound лечится оптимизацией алгоритма, многопроцессностью (для Python — multiprocessing, не threading из-за GIL). I/O-bound — асинхронностью или параллельными запросами.

Ответ 2: дебаг. Когда что-то «зависло» или «странно работает» — надо смотреть на уровень ОС. strace показывает, на каком syscall ваш Python застрял. top — какой ресурс кончился. /proc/[pid]/maps — что в памяти.

Ответ 3: контейнеры. Docker, Kubernetes — это намного больше, чем «упаковка приложения». Это namespaces, cgroups, capabilities, OverlayFS — всё уровня ОС. Без понимания ОС вы не настроите production-готовый контейнер.

VM vs контейнер: что внутри, что снаружи

Ответ 4: безопасность. Понимать, как ваш код может быть атакован, и как защитить — невозможно без понимания privilege levels, namespaces, что такое setuid и почему вы НИКОГДА не запускаете web-сервер от root.


Современная ОС в цифрах

Чтобы прочувствовать масштаб, несколько цифр про Linux:

  • Размер ядра: Linux 6.x — около 30 миллионов строк кода. Это очень большое приложение.
  • Поддерживаемых архитектур: x86, x86_64, ARM (32/64), RISC-V, PowerPC, MIPS, и ещё ~10.
  • Драйверов: тысячи. Каждое устройство (USB, PCI, ACPI) — свой драйвер.
  • Активных разработчиков: примерно 5000 человек регулярно коммитят. Это второй по размеру open-source проект в мире (после Chromium).
  • Команды разработки: Linus Torvalds + сотни мейнтейнеров подсистем. Решения принимаются по техническим причинам, не голосованием.
# Сколько процессов запущено прямо сейчас:
ps -e | wc -l

# Сколько у вас CPUs:
nproc

# Сколько драйверов загружено в ядро:
lsmod | wc -l

# Что за версия ядра:
uname -r

Попробуй сам

Посмотрите на сложность вашей системы прямо сейчас:

# 1. Версия и архитектура ядра:
uname -a

# 2. Сколько CPU и памяти:
nproc
free -h

# 3. Сколько процессов и тредов:
echo "Processes: $(ps -e | wc -l)"
echo "Threads:   $(ps -eL | wc -l)"

# 4. Сколько драйверов загружено:
lsmod | wc -l
lsmod | head -10  # топ-10 для интереса

# 5. Сколько syscalls делает простейшая команда `ls`:
strace -c ls > /dev/null 2>&1 | tail -5

# 6. Где живёт ваш shell в иерархии процессов:
pstree -p $$ | head -5

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


Проверка знанийKnowledge check
Junior спрашивает: 'Если ОС такая сложная, почему её до сих пор не упростили? 30 миллионов строк -- это много. Может, написать заново -- что-то более минималистичное?'
ОтветAnswer
Это классический вопрос, на который есть три ответа. (1) Это пробовалось много раз. Microkernel-системы (Mach, L4, MINIX, GNU Hurd) -- идея сделать ядро минимальным, а драйверы и подсистемы как обычные процессы. Технически элегантно, на практике -- хуже по производительности (много IPC между подсистемами) и медленнее в разработке. Linux mostly выиграл, потому что монолитное ядро легче расширять и быстрее работает. GNU Hurd ведут разработку с 1990, до сих пор не готов к production. (2) Сложность Linux НЕ в самой ОС, а в железе. Из 30 млн строк -- около 25 млн это драйверы. Каждая видеокарта Nvidia, каждая сетевая карта Mellanox, каждый USB-чип -- свой драйвер с тысячами строк. Если вы напишете 'минималистичную ОС' -- она будет работать на 5 моделях железа. Linux -- на десятках тысяч. (3) Сложность -- результат накопленных оптимизаций. CFS scheduler сложный потому, что десятилетиями оптимизировался под разные нагрузки: latency-чувствительные, batch, real-time, kernel-level. Простой round-robin работает, но в 10 раз хуже в реальных нагрузках. Так с каждой подсистемой -- VFS, network stack, memory mgmt. Приватные эксперименты с 'минималистичными ОС' существуют: например, unikernels (rumprun, MirageOS) -- ОС, специализированная под одно приложение. Они интересны для серверного контейнеризированного мира, но не заменяют general-purpose ОС. Итог: Linux не сложен из-за плохого дизайна -- он сложен, потому что мир сложен (тысячи моделей железа) и общие задачи (планирование 1000 процессов одновременно) объективно непросты.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. Какие пять основных функций выполняет современная ОС?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 4