Устройство операционных систем — это очень обширная тема. При ее изучении довольно легко запутаться в деталях и потерять нить обсуждения какого-то конкретного вопроса. В данной главе приводится общий обзор, к которому читатель сможет вернуться в любой момент работы над книгой. Изложение начинается со сведений о предназначении и функциональных особенностях операционных систем. Далее описаны некоторые важные с исторической точки зрения системы и функции операционных систем. Обсуждение этих вопросов позволяет на простых примерах раскрыть некоторые фундаментальные принципы устройства операционной системы и прояснить взаимосвязь между ее различными функциями. Также приведена информация про современные операционные системы. По мере изложения различных тем периодически возникает необходимость обращаться как к фундаментальным, устоявшимся принципам, так и к последним новшествам в устройстве операционных систем.
Операционная система обслуживает пользователей, обращаясь при этом к ресурсам аппаратного обеспечения, в состав которых входит один или несколько процессоров. Кроме того, она управляет вторичной памятью и устройствами ввода-вывода. Поэтому прежде чем приступить к исследованию операционных систем, важно получить некоторое представление о компьютерных системах, на которых они работают.
В данной главе представлен обзор аппаратного обеспечения компьютерных систем. Большинство вопросов освещено кратко, так как предполагается, что читатель знаком с предметом. Однако некоторые из них раскрыты более подробно, исходя из важности этих тем для дальнейшего усвоения материала.
В этой главе изучаются концепции современных операционных систем, связанные с управлением процессами. Мы узнаем, что концепция процессов на самом деле сложнее и тоньше, чем можно себе представить исходя из материала предшествующих глав. По сути, эта концепция объединяет в себе две отдельные, потенциально независимые концепции, одна из которых имеет отношение к владению ресурсами, а другая — к выполнению процессов. В некоторых операционных системах это различие привело к появлению конструкции, известной под названием поток (thread). После рассмотрения потоков мы обратимся к изучению симметричной многопроцессорности (symmetric multiprocessing — SMP). В системе с несколькими процессорами операционная система должна выполнять одновременное планирование выполнения на разных процессорах нескольких процессов. И наконец, мы ознакомим читателя с концепцией микроядра (microkernel), которое является эффективным средством структурирования операционной системы для управления процессами и решения других задач.
Параллельные вычисления: взаимоисключения и многозадачность
Основные вопросы, на которых сосредотачивается внимание разработчиков операционных систем, связаны с управлением процессами и потоками.
Многозадачность: управление множеством процессов в однопроцессорной системе.
Многопроцессорность: управление множеством процессов в многопроцессорной системе.
Распределенные вычисления: управление множеством процессов, выполняемых в распределенной вычислительной системе с множеством компьютеров. Основным примером таких систем являются широко распространенные в последнее время кластеры.
Фундаментальной концепцией этой области, да и разработки операционных систем в целом, является концепция параллельных вычислений (concurrency). Параллельность охватывает множество вопросов разработки, включая вопросы обмена информацией между процессами, разделения ресурсов, синхронизацию работы процессов и распределение процессорного времени между различными процессами. Вы увидите, что эти вопросы возникают не только в многопроцессорной или распределенной вычислительной среде, но и в случае многозадачных систем на базе одного процессора.
Параллельность проявляется в трех различных контекстах.
Множественные приложения: многозадачность разработана для того, чтобы позволить динамически разделять процессорное время между рядом активных приложений.
Структурность приложений: в качестве развития парадигмы модульной разработки и структурного программирования некоторые приложения могут быть разработаны как множество параллельно работающих процессов.
Структура операционной системы: преимущества структурного программирования доступны не только прикладным, но и системным программистам, и, как вы знаете, операционные системы также зачастую реализуются в виде набора процессов или потоков.
В силу важности данного вопроса ему посвящены четыре главы данной книги. В настоящей и следующей главах рассматривается параллельность в контексте многопроцессорности и многозадачности; в главах 13, "Распределенные вычисления, архитектура клиент/сервер и кластеры", и 14, "Управление распределенными процессами", изложены вопросы параллельных вычислений в контексте распределенных вычислений. Хотя оставшаяся часть книги охватывает различные важные темы разработки операционных систем, параллельные вычисления играют главную роль при рассмотрении этих тем.
Данная глава начинается с введения в концепции параллельных вычислений и параллельного выполнения ряда процессов1. Вы узнаете, что основным требованием поддержки параллельных процессов является возможность обеспечения взаимоисключений, т.е. возможность обеспечить работу только одного процесса с остановкой выполнения всех остальных. В следующем разделе будут рассмотрены различные подходы к обеспечению взаимоисключений. Все они являются программными решениями и требуют использования технологии, известной как пережидание занятости (busy waiting). Затем мы остановимся на некоторых аппаратных механизмах, способных обеспечить поддержку взаимоисключений, а также решениях, которые не используют пережидание занятости и могут поддерживаться операционной системой или компиляторами. Мы рассмотрим три подхода: семафоры, мониторы и передачу сообщений.
Для иллюстрации концепций и сравнения, представленных в этой главе подходов используются две классические задачи. Сперва, мы познакомимся с задачей производителей/потребителей, а затем — с задачей читателей/писателей.
Наше изучение параллельных вычислений продолжится в главе 6, "Взаимоблокировка и голодание", и обсуждение механизмов параллельности рассматриваемых нами операционных систем мы отложим до ее конца.
Эта глава продолжает рассмотрение параллельных вычислений и посвящена двум проблемам, доставляющим основные неприятности при работе с параллельными вычислениями: взаимоблокировкам и голоданию. Глава начнется с изложения основных принципов взаимоблокировок, а затем мы узнаем, как их можно предотвратить, обнаружить и устранить. Под конец мы рассмотрим еще одну классическую задачу, иллюстрирующую вопросы синхронизации и взаимоблокировки, а именно — задачу об обедающих философах.
Как и в главе 5, "Параллельные вычисления: взаимоисключения и многозадачность", здесь мы ограничимся рассмотрением проблем в единой системе; распределенным системам посвящена глава 14, "Управление распределенными процессами".
Одним из наиболее сложных аспектов разработки операционной системы является управление памятью. Хотя стоимость памяти постоянно снижается и в результате растет размер основной памяти на современных машинах, достигая гигабайтового диапазона, ее всегда недостаточно для хранения всех программ и структур данных, необходимых активным процессам и операционной системе в целом. Соответственно, одной из центральных задач операционной системы является управление памятью, включающее выгрузку и загрузку блоков данных из вторичной памяти. Од-нако операции ввода-вывода довольно медленные, и их скорость с каждым годом все больше и больше отстает от скорости работы процессора. Для эффективной работы процессора(ов) операционная система должна четко рассчитывать процессы подкачки для минимизации влияния операций ввода-вывода на производительность.