Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

2курсИБ(ОС) / lab5теория

.pdf
Скачиваний:
19
Добавлен:
07.06.2015
Размер:
520.63 Кб
Скачать

Конспект лекций по курсу «Информационные технологии. Операционные системы» (4 семестр, бакалавры по направлению «Информационная безопасность»)

Неформальное определение:

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

История (кратко)

XX век 40-е годы.

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

50-е годы.

Появляются «зачатки» ОС. Машинное время стоит дорого (500$ в час против 4-6$ час оплаты труда программиста. С целью сэкономить время программиста отстраняют от непосредственного взаимодействия с машиной. Он готовит программу и передает ее оператору. Задача оператора — обеспечивать постоянную загрузку машины. В связи с этим возникают утилиты, облегчающие переход от работы одной программы к работе другой программы. ОС можно считать однопоточными системами пакетной обработки: сгруппированные на ленту программы обрабатываются последовательно.

60-е годы.

Первая половина.

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

Вторая половина.

В 1964 г. IBM представляет свою серию OS/360. Важно: разные модели компьютеров были разработаны в рамках идеи о полной совместимости аппаратных средств. Разделение ресурсов было перенесено на процессорное время. Результат: программист вновь получил возможность взаимодействовать с компьютером в диалоговом режиме, например, с терминала (консоли).

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

Еще одна важная технология — виртуальная память. TSS, Multics, CP/CMS — все они уже имели возможность обращаться к большему пространству адресов, чем наличествовало физически.

Multics разрабатывалась на EPL – подмножестве PL/1 (не на ассемблере).

В конце 60-х началась разработка ARPAnet, которая стала прародительницей Internet.

70-е годы.

ОС — многорежимные мультипрограммные системы с разделением времени и пакетной

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

Возникновение и стандартизация локальных сетей, появление стандартов TCP/IP, Ethernet. Появление первых ПК.

80-е годы.

1981 — первый ПК от IBM. Массовое использование ПК и рабочих станций. Распространение графических пользовательских интерфейсов (GUI). В конце 80-х Internet был разрешен к коммерческому (а не только военному использованию). В 1989 Тим Бернерс Ли (CERN) разработал гипертекст. Сетевые технологии приобретают важное значение и становятся «стандартной» частью ОС.

90-е годы.

Массовое производство приводит к существенному удешевлению аппаратных средств. Развитие сетевых технологий — к распределенным вычислениям. Операционные системы Windows и Macintosh — дружественные к ordinary user. Появление технологии Plug-and-Play. Рост числа приложений за счет предоставления программистам API.

Распространение технологии ООП.

2000-е годы Параллелизм. Многопроцессорные системы. Новые стандарты и форматы.

Взаимодействие пользователя с ОС

Может осуществляться либо через пользовательское приложение, либо через специальное приложение-оболочку.

Неформальное определение:

Процесс — запущенная на выполнение программа (подробнее — позже).

Совокупность программ, объединяющая основные компоненты ОС, называется ядром. Как правило, к этим компонентам относятся:

планировщик процессов (process sheduler) (когда и сколь долго процесс будет обрабатываться процессором); (на будущее — как осуществляется передача ресурсов между процессами)

диспетчер памяти (memory manager) (каким образом распределяется память между процессами и что делать, если не хватает); (на будущее — процессы не должны иметь доступ к «чужой» памяти)

диспетчер ввода / вывода ( i/o manager) (обслуживает запросы ввода данных с аппаратных устройств и вывода на них); (драйвера устройств — фактически компоненты расширения ОС)

диспетчер межпроцессного взаимодействия (ipc, interprocess communication manager) (позволяет процессам взаимодействовать между собой);

диспетчер файловой системы (file system manager) (упорядочивает поименованные объекты на запоминающих устройствах и предоставляет интерфейс для доступа к данным на этих устройствах); (на будущее — планировщик дисковых операций отвечает за переупорядочение запросов дискового ввода / вывода для повышения производительности и сокращения времени ожидания; RAID – Redundant Array of Independent Disks, массив независимых дисковых накопителей с избыточностью тоже может оказать «аппаратное» влияние на ускорение этого процесса).

Свойства ОС:

эффективность (efficient): высокая производительность, малое время обработки запросов (в среднем) (нужно организовать работу большого количества приложений);

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

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

расширяемость (extensible): может адаптироваться к новым технологиям, способна решать задачи, изначально не предусмотренные при разработке ОС

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

защищенность (secure): препятствует пользователям и ПО в получении несанкционированного доступа к сервисам и ресурсам

интерактивность (interactive): позволяет приложениям быстро реагировать на действия пользователей и другие события в системе.

практичность (usable): в некотором смысле универсальность (с точки зрения пользователя). Важно: набор приложений под ОС, поддержка ряда интерфейсов.

Архитектура ОС

Исторически первая: монолитная.

Примеры: OS/360, Linux (из-за этого сильно и резко дискутировали Торвальдс и Таненбаум) Каждый компонент включен в ядро и может непосредственно взаимодействовать с другими компонентами. Ядро выполняется с неограниченными правами доступа к ресурсам.

С одной стороны — высокая эффективность (низкоуровневое взаимодействие), с другой — трудно найти источник сбоев / ошибок; более высокая уязвимость для вредительского кода.

Многоуровневая.

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

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

Минусы: запрос на обслуживание процесса проходит многие уровни, производительность системы снижается. Примеры: THE, в некотором смысле идеи многоуровневости реализованы в Win XP+, Linux

Микроядро.

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

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

Недостатки: интенсивное межмодульное взаимодействие. Примеры: Symbian OS, Minix, Mac OS

Сетевые и распределенные ОС Сетевая — предоставляет процессам доступ к ресурсам (например, файлам), которые

расположены на других компьютерах сети. Принцип — клиент-серверное взаимодействие. Важный компонент — сетевая файловая система. Примеры: Novell Netware, LANtastic, функции поддерживают многие «обычные» (Win, Unix)

Распределенные — «иллюзия объединения» многочисленных компьютеров в один мощный. Пример: Chord (MIT), Amoeba (университет Врийе в Амстердаме).

Процессы.

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

Термин впервые появился в Multics (следует отметить, что в Multics впервые появились ACL

– Access Control List, представлявшие собой перечень разрешений для сегментов памяти; потом появился и AIM – Access Isolation Mechanism, мандатный контроль доступа). Процесс

— это логический объект. Он обладает собственным адресным пространством, которое обычно состоит из области команд (text region), области данных (data region) и области стека (stack region).

Область команд — программный код, выполняемый процессором.

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

Область стека — инструкции и локальные переменные (при вызове процедур).

Жизненный цикл процесса.

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

Процесс может выполняться (running state) — т. е. ему выделен ЦП; может быть готовым (ready state) — если может сразу использовать процессор при условии, что ему он будет выделен; может быть заблокирован (blocked state) — для того, чтобы продолжить работу, ему необходимо дождаться наступления некоторого события (например, завершения операции ввода / вывода).

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

ОС поддерживает список готовых к выполнению процессов и список заблокированных процессов.

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

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

Когда создается новый процесс, ОС делает ряд вещей.

1.Процессу присваивается PID (Personal IDentification number)

2.Создается блок управления процессом (Process Control Block) – он же дескриптор процесса

ВPCB обычно содержится следующая информация:

PID

текущее состояние процесса

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

приоритет процесса

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

указатель на родительский процесс (parent process)

указатели на дочерние процессы (child processes)

указатели данных и инструкций процесса в памяти

указатели выделенных процессу ресурсов (например, файлов)

Кроме этого, в блоке управления процессом хранится содержимое регистров, называемое контекстом выполнения (execution context) процессора перед выходом из состояния выполнения.

Все это хранится в таблице процессов.

ОС может (и должна) выполнять следующие операции над процессами:

создание

уничтожение

приостановка

возобновление

изменение приоритета

блокирование процесса

пробуждение

запуск

обеспечение взаимодействия процессов

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

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

Новая схема с учетом состояний приостановки.

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

Переключение должно быть максимально прозрачным (процессы не должны этого «замечать») и быстрым — во время этой операции процессор полностью занят задачей переключения.

Прерывания.

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

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

Если прерывание вызвано другими событиями, не связанными с выполнением текущих инструкций — то это асинхронные прерывания. Аппаратура формирует асинхронные прерывания.

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

Intel — процессоры (начиная с IA 32) поддерживают прерывания и исключения (последние свидетельствуют об аппаратной или программной ошибке).

Взаимодействие процессов

Сигналы — программные прерывания, уведомляющие процесс о наступлении определенного события.

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

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

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

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

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

Реализация этого механизма (например) — канал (pipe), защищенная область памяти, выступающая в качестве буфера, позволяющего нескольким процессам обмениваться данными.

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

Потоки (threads)

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

Если ЯП позволял обратиться к примитивам / функциям ОС, то можно было реализовать несколько потоков в одном приложении.

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

В настоящее время в состав большинства языков универсального назначения включены примитивы для реализации параллелизма — такие примитивы присутствуют в Java, в языках семейства .NET, в Python, во многих других. Отметим, что в Delphi / C++ для организации многопоточных приложений фактически обращаются к примитивам ОС.

Иногда потоки называют легковесными процессами (LWP, lightweighted process), в то время как сами процессы называют тяжеловесными (HWP, heavyweight process). Потоки одного процесса обладают общим доступом к большинству принадлежащих ему ресурсов; в первую

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

Увы, поддержку потоков нельзя назвать стандартизированной, хотя существует спецификация POSIX (Pthread) (реализованная во многих ОС, в т.ч. Linux, Win XP (и далее), Solaris). Поэтому, хотя поддерживают потоки многие ОС, реализация этой поддержки может заметно отличаться, что не позволяет делать многопоточные приложения переносимыми (или, по крайней мере, легко переносимыми).

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

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

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

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

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

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

Заметим, что наряду с «классическим» параллелизмом распространен и другой его вид, который принято называть «распределенными вычислениями в компьютерных сетях». В этом случае ОС, в первую очередь, является диспетчером ресурсов.

Жизненный цикл потока

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

В качестве примера рассмотрим группу состояний, основываясь на реализации потоков в Java.

ЖЦ потока в Java начинается с его рождения (born), после чего он переходит в состояние готовности (ready). В ряде ОС запуск потока происходит сразу же в момент создания, промежуточных состояний не требуется. Среди потоков, находящихся в состоянии

готовности, система выбирает поток с наивысшим приоритетом, и этот поток переходит в состояние выполнения.

Поток может перейти из состояния выполнения в следующие состояния:

тупиковое (также dead); если он выполнил все инструкции или же был завершен по иным причинам; когда поток перешел в это состояние, все его ресурсы высвобождаются, и он удаляется из системы

блокировка (blocked) — если поток ожидает завершения операции ввода / вывода; когда эта операция будет завершена, поток может перейти в состояние готовности и продолжить выполнение, как только процессор освободится

ожидание (waiting) — если поток находится в состоянии ожидания определенного события (отклик пользователя, сигнал от другого потока, etc). Как только его уведомляет (notifies) о наступлении события или же будит (awakens) другой поток, этот поток переходит в состояние готовности

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

ОС может выполнять над потоками и процессами много общих операций:

создание;

завершение;

приостановка;

возобновление;

засыпание;

пробуждение.

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

Операции, не имеющие эквивалента среди операций над процессами:

отмена (cancel) — поток или процесс могут завершить выполнение другого потока путем его отмены. Однако, отмена выполнения потока не гарантирует его завершения (потоки могут запрещать либо маскировать прием сигналов отмены; единственное — они не могут маскировать сигналы аварийного завершения)

присоединение (join). В ряде ОС (Windows XP+) при инициализации процесса создается первичный поток (primary thread). Завершение выполнения этого потока означает завершение выполнения всего процесса. Поэтому первичный поток переходит в состояние сна, пока не завершат работу все созданные им потоки. Именно это и называют присоединением: если один поток присоединяет к себе другой, то выполнение первого приостанавливается до завершения работы второго.

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

Потоки уровня пользователя (user-level thread; редко используемое название для потоков, поддерживающих кооперативную многозадачность — fiber, волокно) могли быть реализованы уже в первых ОС. ОС запускает многопоточный процесс целиком и рассматривает его в виде одного (общего) контекста выполнения. Фактически это отношение «многие-к-одному». Операции планирования и запуска потоков вызываются библиотеками уровня пользователя, ОС не знает, из скольких потоков состоит процесс, выдает на процесс один квант времени, как его делить — решает процесс.

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

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

Потоки уровня ядра (kernel-level thread) связывают каждый поток с отдельным контекстом выполнения (и это отношение «один-к-одному»). При этом потоки ядра сохраняют «легковесность», т. е. разделяют адресное пространство процесса.

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

Соседние файлы в папке 2курсИБ(ОС)