- •С. Ф. Храпский
- •Удк 681.3
- •Оглавление
- •Предисловие
- •Введение
- •1. Управление процессами в автономных однопроцессорных вычислительных машинах
- •1.1. Понятия вычислительного процесса и ресурса
- •1.2. Планирование процессов
- •1.3. Межпроцессное взаимодействие
- •1.4. Понятия потока («нити») и многопоточности
- •Контрольные вопросы и задания
- •2. Управление ресурсами в автономных однопроцессорных компьютерах
- •2.1. Управление памятью
- •Управление вводом-выводом
- •2.3. Управление файлами и файловая система
- •Контрольные вопросы и задания
- •3. Управление процессами и ресурсами в автономных многопроцессорных вычислительных машинах
- •3.1. Реализация операционных систем многопроцессорных вычислительных машин
- •Планирование и синхронизация в многопроцессорных вычислительных машинах
- •Контрольные вопросы и задания
- •4. Управление процессами и ресурсами в многомашинных вычислительных системах
- •4.1. Способы организации управления процессами
- •И ресурсами в многомашинных вычислительных системах
- •4.2. Понятия сетевой и распределенной операционных систем
- •4.3. Варианты реализации распределенных операционных систем
- •Контрольные вопросы и задания
- •5. Общие концепции разработки операционных систем
- •5.1. Основные принципы построения операционных систем
- •5.2. Архитектурные особенности проектирования операционных систем
- •5.3. Принципы построения системных и прикладных программных интерфейсов
- •Контрольные вопросы и задания
- •6. История развития операционных систем и эволюция их функциональных характеристик
- •6.1. Операционные системы разных этапов разработки вычислительных машин
- •6.2. История развития и характеристики операционных систем unix
- •6.3. История развития и характеристики операционных систем семейства Windows
- •Контрольные вопросы и задания
- •7. Пример практической реализации операционной системы: unix
- •7.1. Обзор системы unix
- •7.1.1. Общие представления
- •7.1.2. Интерфейсы системы unix
- •7.1.3. Оболочка и утилиты системы unix
- •7.1.4. Структура ядра системы unix
- •7.2. Процессы в unix
- •7.2.1. Основные понятия
- •7.2.2. Реализация процессов в unix
- •7.2.3. Планирование в системе unix
- •7.3. Управление памятью в unix
- •7.3.1. Основные понятия
- •7.3.2. Реализация управления памятью в unix
- •7.4. Ввод-вывод в системе unix
- •7.4.1. Основные понятия
- •7.4.2. Реализация ввода-вывода в системе unix
- •7.4.3. Потоки данных в unix
- •7.5. Файловые системы unix
- •7.5.1. Основные понятия
- •7.5.2. Реализация классической файловой системы unix
- •7.5.3. Реализация файловой системы Berkeley Fast
- •7.5.4. Реализация файловой системы Linux
- •7.5.5. Реализация файловой системы nfs
- •7.6. Безопасность в unix
- •7.6.1. Основные понятия
- •7.6.2. Реализация безопасности в unix
- •Контрольные вопросы и задания
- •8. Пример практической реализации операционной системы: Windows 2000
- •8.1. Обзор структуры операционной систем Windows 2000
- •8.1.1. Структура системы
- •8.1.2. Реализация объектов
- •8.1.3. Подсистемы окружения
- •8.2. Процессы и потоки в Windows 2000
- •8.2.1. Основные понятия
- •8.2.2. Межпроцессное взаимодействие
- •8.2.3. Реализация процессов и потоков
- •8.2.4. Загрузка Windows 2000
- •8.3. Управление памятью в Windows 2000
- •8.3.1. Основные понятия
- •8.3.2. Реализация управления памятью
- •8.4. Ввод-вывод в системе Windows 2000
- •8.4.1. Основные понятия
- •8.4.2. Реализация ввода-вывода в Windows 2000
- •8.5. Файловые системы Windows 2000
- •8.5.1. Файловые системы типа fat
- •8.5.2. Файловая система типа ntfs
- •8.6. Безопасность в Windows 2000
- •8.6.1. Основные понятия
- •8.6.2. Реализация защиты в Windows 2000
- •Контрольные вопросы и задания
- •Заключение
- •Библиографический список
- •Словарь терминов и определений
- •Алфавитно-предметный указатель
- •Храпский Сергей Филиппович операционные системы, среды и оболочки основные теоретические сведения
- •644099, Омск, ул. Красногвардейская, 9
7.2. Процессы в unix
7.2.1. Основные понятия
Единственными активными сущностями в системе UNIX являются процессы. Процессы UNIX очень похожи на классические последовательные процессы, которые рассматривались в разделе 1. Каждый процесс запускает одну программу и изначально получает один поток управления. Другими словами, у процесса есть один счетчик команд, указывающий на следующую исполняемую команду процессора. Большинство версий UNIX позволяют процессу после того, как он запущен, создавать дополнительные потоки. UNIX представляет собой многозадачную систему, так что несколько независимых процессов могут работать одновременно. У каждого пользователя может быть одновременно несколько активных процессов, так что в большой системе могут одновременно работать сотни и даже тысячи процессов. Действительно, на большинстве однопользовательских рабочих станций (даже без участия пользователя) работают десятки фоновых процессов, называемых демонами (daemon). Они запускаются автоматически при загрузке системы. Демоны позволяют планировать в системе UNIX активность на минуты, часы, дни и месяцы вперед, управлять входящей и исходящей электронной почтой, очередями на принтер, проверять наличие свободных страниц памяти и т. д. Демоны реализуются в системе UNIX относительно просто, так как каждый из них представляет собой отдельный процесс, независимый ото всех остальных процессов.
В операционной системе UNIX посредством системного вызова fork создается точная копия исходного процесса (так называемого родительского процесса). Новый процесс называется дочерним процессом. У родительского и у дочернего процессов есть свои собственные образы памяти. Если родительский процесс впоследствии изменяет какие-либо свои переменные, изменения остаются невидимыми для дочернего процесса, и наоборот.
Открытые файлы совместно используются родительским и дочерним процессами. Это значит, что если какой-либо файл был открыт до выполнения системного вызова fork, он останется открытым в обоих процессах и в дальнейшем. Изменения, произведенные с этим файлом, будут видимы каждому процессу. Такое поведение является единственно разумным, так как эти изменения будут также видны любому другому процессу, который тоже откроет этот файл.
У родительского процесса может быть много дочерних процессов. Поскольку у дочерних процессов также могут быть дочерние процессы, исходный процесс может создать целое дерево детей, внуков, правнуков и т. д.
В системе UNIX процессы могут общаться друг с другом с помощью разновидности обмена сообщениями. Можно создать канал между двумя процессами, в который один процесс может писать поток байтов, а другой процесс может его читать. Эти каналы иногда называют трубами. Синхронизация процессов достигается путем блокирования процесса при попытке прочитать данные из пустого канала. Когда данные появляются в канале, процесс разблокируется.
Процессы также могут общаться другим способом: при помощи программных прерываний. Один процесс может послать другому так называемый сигнал. Процессы могут сообщить системе, какие действия следует предпринимать, когда придет сигнал. У процесса есть выбор: проигнорировать сигнал, перехватить его или позволить сигналу убить процесс (действие по умолчанию для большинства сигналов). Если процесс выбрал перехват посылаемых ему сигналов, он должен указать процедуры обработки сигналов. Когда сигнал прибывает, управление сразу же передается обработчику. Когда процедура обработки сигнала завершает свою работу, управление снова возвращается в то место процесса, в котором оно находилось, когда пришел сигнал. Обработка сигналов аналогична обработке аппаратных прерываний ввода-вывода. Процесс может посылать сигналы только членам его группы процессов, состоящей из его прямого родителя, всех прародителей, братьев и сестер, а также детей (внуков и правнуков). Процесс может также послать сигнал сразу всей своей группе за один системный вызов.
Сигналы в UNIX используются и для других целей. Например, если процесс выполняет вычисления с плавающей точкой и непреднамеренно делит число на 0, он получает сигнал исключения при выполнении операции с плавающей точкой. Сигналы UNIX описываются стандартом POSIX. В большинстве систем UNIX также имеются дополнительные сигналы, но программы, использующие их, могут оказаться непереносимыми на другие версии UNIX.
В первых версиях системы UNIX понятия потоков не существовало. После введения этого понятия и возможности управления потоками были стандартизированы соответствующие системные вызовы в виде части стандарта POSIX – P1003.1c.
В исходном варианте стандарта POSIX не указывается, должны ли потоки реализовываться в пространстве ядра или в пространстве пользователя. Преимущество потоков в пользовательском пространстве состоит в том, что они легко реализуются без необходимости изменения ядра, а переключение потоков осуществляется очень эффективно. Недостаток потоков в пространстве пользователя заключается в том, что если один из потоков заблокируется (например, на операции ввода-вывода, семафоре или страничном прерывании), все потоки процесса блокируются. Ядро полагает, что существует только один поток, и не передает управление процессу потока, пока блокировка не снимется. Таким образом, системные вызовы, определенные в части стандарта P1003.1c были подобраны так, чтобы потоки могли быть реализованы любым способом. До тех пор, пока пользовательские программы четко придерживаются семантики стандарта POSIX – P1003.1c, оба способа реализации работают корректно. Когда используется системная реализация потоков, они являются настоящими системными вызовами. При использовании потоков на уровне пользователя они полностью реализуются в динамической библиотеке в пространстве пользователя.
Синхронизация потоков может осуществляться при помощи мьютексов. Как правило, мьютекс охраняет какой-либо ресурс, например буфер, совместно используемый двумя потоками. Чтобы гарантировать, что только один поток в каждый момент времени имеет доступ к общему ресурсу, предполагается, что потокиблокируют (захватывают) мьютекс перед обращением к ресурсу и разблокируют (отпускают) его, когда ресурс им более не нужен. До тех пор пока потоки соблюдают данный протокол, состояния состязания можно избежать. Напомним, что название мьютекс (mutex) образовано от английских слов mutual exclusion – взаимное исключение, так как мьютексы подобны двоичным семафорам, то есть семафорам, способным принимать только значения 0 и 1. Таким образом мьютекс может находиться в одном из двух состояний: блокированный и разблокированный. Поток может заблокировать мьютекс с помощью системного вызова. Если мьютекс уже заблокирован, то поток, обратившийся к этому вызову, блокируется. Когда поток, захвативший мьютекс, выполнил свою работу в критической области, он должен освободить мьютекс, обратившись к соответствующему системному вызову.
Мьютексы предназначены для кратковременной блокировки, например для защиты совместно используемой переменной. Они не предназначаются для долговременной синхронизации, например для ожидания, когда освободится накопитель на магнитной ленте. Для долговременной синхронизации применяются так называемые переменные состояния. Переменные состояния используются следующим образом: один поток ждет, когда переменная примет определенное значение, а другой поток сигнализирует ему изменением этой переменной. Например, обнаружив, что нужный ему накопитель на магнитной ленте занят, поток может обратиться к системному вызову, задав в качестве параметра адрес переменной, которую все потоки согласились связать с накопителем на магнитной ленте. Когда поток, использующий накопитель на магнитной ленте, наконец, освободит это устройство, он обращается к соответствующему системному вызову, чтобы изменить переменную состояния и тем самым сообщить ожидающим потокам, что накопитель свободен. Если ни один поток в этот момент не ждет, когда освободится накопитель на магнитной ленте, этот сигнал просто теряется. Другими словами, переменные состояния не считаются семафорами.