скачать 3. Операционная платформа. Классификация операционных систем по типу централизации. Классификация по особенностям управления ресурсами. Классификация по особенностям областей использования. Процессы. Процессы и потоки (нити) управления. Процессы с поддержкой многопоточности. Замечание: часть материала данной лекции соответствует различным разделам книг
В качестве дополнительного материала к данной лекции рекомендуются открытые курсы 3. «Архитектуры и топологии многопроцессорных систем» Богданов А.В., Станкова Е.Н., Мареев В.В., Корхов В.В. http://www.intuit.ru/department/hardware/atmcs 4. «Архитектура и организация ЭВМ» Гуров В.В., Чуканов В.В. http://www.intuit.ru/department/hardware/archhard2/ 5. «Архитектурно – ориентированная оптимизация программ» Долгов Ю.В., Шкурко Д.В. http://www.i-lab.nsu.ru/index.php?file=spec Материал к лекции №3 (в том числе и дополнительный для самостоятельного изучения). Лекция – 2 часа, самостоятельная работа – 2 часа, практикум – 2 часа, итого – 6 часов. ^ Операционная платформа. Определения и классификация 1 1. Введение 2 2. Введение в операционные системы 3 2.1. Основные понятия и определения 3 2.2. История и эволюция операционных систем 5 2.2.1.Поколения операционных систем 6 2.2.2. Краткий обзор истории создания операционных систем 6 2.2.3. Классификация операционных систем 8 2.2.3.1. Классификация по типу централизации 8 2.2.3.2. Классификация по особенностям алгоритмов управления ресурсами 10 2.2.3.3. Классификация по особенностям аппаратных платформ 11 2.2.3.4. Классификация по областям использования 11 2.2.3.5. Классификация по типу архитектуры ядра системы 12 3. Процессы 14 3.1. Процессы и потоки (нити) управления 14 3.1.2. Понятие процесса 14 3.1.3. Процессы с поддержкой многопоточности. 15 3.1.4. Об использовании потоков 18 3.1.5. О безопасности использования фрагментов кода в многопоточных программах 19 ^ 5. Определение временных затрат на реализацию параллельных конструкций в OpenMP 20 6. Задание 22 1. ВведениеОперационная платформа – один из трех «китов» «системного подхода», как показано на рис. 1: ![]() Рис.1. Роль операционной платформы в «системном» подходе, определяемом методологией программирования Изучение операционных систем необходимо, во-первых, любому программисту вообще, как «основы всего сущего». [1] «Изучение механизма и структуры операционных систем необходимо по следующим причинам: Основные идеи, концепции и алгоритмы, лежащие в основе операционных систем, применимы ко многим другим областям программирования, и особенно к системному программированию; Операционная система – большая и сложная программа, на примере которой можно изучить вопросы создания сложных программных продуктов; … Такие популярные программные продукты, как базы данных, могут рассматриваться как надстройки над операционными системами.» Во – вторых, «параллельному» программисту информация об операционных платформах необходима в особенности, так как
На рис. 2 показан пример параллельного языка программирования с регистрацией пользовательских потоков как потоков ядра операционной системы. Суть регистрации заключается в том, что для каждого пользовательского потока создается поток ядра и все планирование работы потоков осуществляется ядром на основе единой стратегии. ![]() Рис. 2. Пример параллельного языка программирования с регистрацией пользовательских потоков как потоков ядра операционной системы. ^ [1] «Операционная система (ОС) – это часть программного обеспечения, выступающая в качестве интерфейса между приложениями (и пользователями) и аппаратурой компьютера Операционная система выполняет две основные функции: 1. Предоставление пользователю-программисту вместо реальной аппаратуры компьютера расширенной виртуальной машины, с которой удобно работать
2. Повышение эффективности использования компьютера за счет рационального управления его ресурсами. Ресурсы операционной системы можно разделить на две группы (рис. 3.)
![]() Рис.3. Классификация ресурсов Обратим внимание на то, что практически каждому аппаратному ресурсу соответствует некоторый программный ресурс, тесно с ним связанный (например, процессор и процесс) «Образно говоря, основной функцией операционной системы можно считать чародейство – превращение системы в нечто большее, чем есть на самом деле. Например, операционная система может создать иллюзию одновременного исполнения нескольких программ на одном процессоре. В итоге пользователь воспринимает виртуальную машину как компьютер, имеющий архитектуру, отличную от реально существующей.» Так, параллельные программы для технологий параллельного программирования в общей (например, OpenMP) и распределенной памяти (например, MPI), вполне можно тестировать на правильность работы на однопроцессорной машине, если установлена подходящая операционная система (например, последние версии Windows и Linux), при наличии соответствующего программного обеспечения. Одно плохо – скорость работы программы будет практически совпадать с последовательным вариантом! ![]() ![]() ![]() ![]() ![]() ![]() ![]() Рис. 4. Виртуальные параллельные архитектуры, создаваемые операционной системой «Ядро операционной системы – модули, выполняющие основные функции операционной системы. Эти модули обычно поддерживают управление процессами, памятью, устройствами ввода-вывода. Код ядра операционной системы исполняется в привилегированном режиме работы процессора. Некоторые компоненты операционной системы представляют собой обычные приложения в стандартном для данной операционной системе формате. Их называют вспомогательными модулями операционной системы. Поэтому часто бывает сложно провести границу между операционной системой и приложениями. Обычно решение о принадлежности некоторой программы операционной системе принимает производитель. Многие компоненты систем программирования …, часто вводятся производителями ОС в качестве ее вспомогательных модулей.» ^
[1] « Принято выделять следующие исторические поколения операционных систем.
^ [1] «Первая операционная система появилась в середине 50 годов 20 века. Она была создана в исследовательской лаборатории компании General Motors для компьютера IBM-702. Практически до середины 60 годов 20 века распространялась бесплатно. В СССР одним из первых подобий операционных систем была система интерпретации обращений к стандартным подпрограммам ИС-2 для М – 20 (1959). Она была построена по принципу динамической загрузки библиотечных подпрограмм в область оперативной памяти, выделяемой программистом. Подпрограммы по мере обращения к ним вызывались на рабочее поле, организованное частью как стек (для «фиксируемых» подпрограмм), частью как очередь, откуда они вытеснялись по мере переполнения поля, но могли обращаться при новых обращениях. ….Дадим краткую характеристику некоторым из них. 1961 г.- Atlas. Эта операционная система была разработана в Манчестерском университете (Англия). Многие особенности, впервые появившиеся в ней (например, страничное управление памятью)сейчас являются стандартными частями операционных систем. 1962 г. – CTSS. Система была разработана в Массачусетстком технологическом институте (США) как экспериментальная система с механизмом разделения времени. 1965. – XDS – 940. Система разработана в университете Беркли (США). Эта была операционная система с разделением времени. Она давала возможность пользовательской программе определять процессы и работать с ними посредством системных вызовов. 1966. – Multics – Система также была разработана в Массачусетском технологическом институте и являлась развитием системы CTSS. В свою очередь эта система является предшественницей операционной системы UNIX. 1966 г. – OS/360. Операционная система для большого семейства компьютеров IBM/360 была написана на ассемблере тысячами программистов и представляла собой миллионы строк кода. В 1971 году была выпущена ДОС ЕС 1.0 – полный функциональный отечественный аналог DOS/360 MFT. При переработке текста DOS/360 разработчики сделали большое количество дополнений и улучшений. Система функционировала на семействе ЕС ЭВМ. В результате отечественным пользователям стали доступны прикладные программные продукты, выпущенные за рубежом. 1967. – Диспетчер – 68. Первая операционная система для БЭСМ –6 была создана в ИТМ и ВТ под руководством Л.Н. Королева. Она была предназначена для управления совместной работой ЭВМ, подготовки и решения задач в мультипрограммном режиме. 1968 г. – THE. Система создана в технической школе Эйдховена (Голландия). Система имела слоистую архитектуру и могла работать с параллельными процессами, выполняя синхронизацию с помощью семафоров. 1971. – ОС Диспак. Система создавалась В.Ф. Тюриным и группой разработчиков для БЭСМ - 6 , а затем для МВК Эльбрус. 1974 г. – CR/M. Эта система явилась родоначальником операционных систем для микропроцессоров, первоначально для 8-битовых. Отдельно будем вести разговор об истории эволюции двух доминирующих в настоящее время семейств операционных систем. Семейство UNIX. Официальной датой рождения операционной системы Unix считают 1 января 1970 года. С этого времени любая система Unix отчитывает свое системное время. Реально первая версия этой операционной системы была создана в 1969 голу двумя очень талантливыми людьми – Кеном Томпсоном (Ken Tompson) и Деннисом Ритчи (Dennis Ritchie). Истории и эволюции Unix в Интернете посвящено много страниц, например http://www.levenes.com/unix/. Существует множество версий, диалектов и клонов Unix, включая System V и BSD –два главных направления развития. Большое количество версий Unix появилось уже в конце 1970-х благодаря тому, что исходный текст системы был широко распространен. Для обеспечения переносимости программ институтом IEEE был разработан стандарт POSIX, определяющий минимальный интерфейс, который должны поддерживать совместимые диалекты Unix. Клон Linux, созданный финским студентом Линусом Торвальдсом, является одним из наиболее популярных среди широкого круга пользователей в настоящее время. О том, как правильно писать – UNIX или Unix. Питер Салюс (Peter H. Salus) (Salus 1994) приводит слова Дагласа Макироля (Douglas Mcllroy) о том, что написание UNIX заглавными буквами является серьезной ошибкой. Мы далее будем придерживаться этой рекомендации и писать Unix. Семейство Windows. Первым представителем этого семейства является система MS-DOS 1.0 компании Microsoft. Система поставлялась с персональным компьютером IBM PC, начиная с 1981 года. Версия MS-DOS 3.0 появилась в 1986, а 7.0 – 1995 году. Добавление графического пользовательского интерфейса к MS-DOS породило в 1985 году систему Windows 1.0. Спустя 10 лет, в 1995 году была выпущена версия Windows 95, далее Windows 98, и, наконец, Windows ME в 2000 году. Все эти версии имели тесную связь с 16-ти разрядной MS-DOS, что существенно ограничивало их возможности. Совершенно новая, полностью 32-разрядная операционная система Windows NT – 3.1. была выпущена в 1993 году. Массовый переход пользователей на эту систему происходил медленно, но верно. В 1996 году вышла система Windows NT 4.0. В2001 – Windows 2000. В 2002 – Windows XP. В последние годы получили широкую известность операционные системы для мобильных устройств, например, Palm OS, Symbian OS, Nucleus, а также Windows CE.NET. Существуют даже «учебные» операционные системы, например OC NACHOS (Not Another Completely Heuristic Operating System), первая версия которой была создана Уэйном Кристофером (Wayne Christopher), Стивом Проктером (Steve Procter) и Томасом Андерсеном (Thomas Anderson) в январе 1992 года. Эта операционная система используется практически во всех университетах мира при выполнении студентами самостоятельных заданий по соответствующему учебному курсу (http://www.stanford.edu/class/cs140/projects/).» ^ 2.2.3.1. Классификация по типу централизации[1] «В основу первой и основной классификации положим степень централизации (связности) операционной системы. Операционные системы ![]() ![]() ![]() Централизованные Сетевые Распределенные ![]() ![]() Однопроцессорные Многопроцессорные Рис. 5. Классификация по типу централизации. Эта классификация принимает во внимание особенности аппаратных платформ, для которых операционные системы создаются.
Существует интересное обоснование данной классификации. В главе 6. было отмечено, что основной характеристикой классификации параллельных и распределенных архитектур считают наличие общей или распределенной(локальной для каждого из узлов) памяти. Исходя из этого, вычислительные системы можно разделить на два класса.
Программное обеспечение можно также разделить на два класса. Программное обеспечение с сильными связями. Сюда относятся программы, которые при исполнении на нескольких вычислительных модулях в большой степени являются связанными между собой. Программное обеспечение со слабыми связями. Оно позволяет вычислительным модулям быть независимым друг от друга, но при необходимости взаимодействовать ограниченным количеством способов. В результате можно получить четыре различных комбинации между этими парами, три из котрых явля.тся осмысленными и определяют следующие типы операционных систем (рис. 6.) Параллельные и распределенные компьютеры ![]() ![]() Слабые связи (каждый компьютер имеет свою память) Сильные связи (многопроцессорные с общей памятью) Централизованная ОС ![]() ![]() ![]() ![]() ![]() ![]() Сетевая ОС Распределенная ОС Сильные связи Слабые связи ![]() ![]() Программное обеспечение Рис. 6. Обоснование классификации по типу централизации. ^ [1] «Классификация по особенностям алгоритмов управления ресурсами имеет следующие аспекты. 1. Поддержка многозадачности, а именно:
2. Поддержка многопользовательского режима, а именно:
3. Поддержка многопоточности. Многопоточные операционные системы дают возможность разделять время не только между процессами, но и между отдельными ветвями процессов - потоками 4. Поддержка многопроцессорной обработки. Многопроцессорные операционные системы реализуют более сложные алгоритмы управления ресурсами, предоставляют возможность работать с несколькими процесссорами 5. В операционных системах отдельным направлением идет концепция системы виртуальных машин. Такие операционные системы допускают одновременную работу нескольких полноценных операционных систем, создавая иллюзию того, что ЭВМ находится в их полном распоряжении.» ^ [1] «Специфика аппаратных средств, как правило, отражается на специфике операционной системы.» В лекции 2 была рассмотрена «…функциональная классификация компьютеров. Каждый из типов компьютеров в этой классификации имеет определенные свойства, оказывающие непосредственное влияние на свойства операционных систем. Обратим внимание на то, что наибольший интерес в настоящее время вызывают следующие группы операционных систем:
^ [1] «По особенностям областей использования многозадачные операционные системы могут быть разделены на три типа:
Многие операционные системы совмещают в себе свойства систем различных типов. Например, часть задач выполняется в режиме разделения времени, а часть – в режиме реального времени.» ^ [1] «Существуют следующие основные разновидности архитектуры ядра. Монолитное ядро. Такое ядро компонуется как одно программа, работающая в привилегированном режиме и использующая быстрые переходы с одной процедуры на другую.(рис. 7. А) Слоистое ядро. В этом случае компоненты операционной системы образуют уровни с хорошо продуманной функциональностью и интерфейсом. Как и в предыдущем случае, компоненты работают в привилегированном режиме. (рис. 7. б) Микроядро. Микроядро выполняет минимум функций по управлению аппаратурой. Обычно в него включаются машинно зависимые программы, некоторые функции управления процессами и обработка прерываний. Функции более высокого уровня выполняют специализированные компоненты операционной системы: сервер процессора, файловый сервер и т.д. Эти компоненты работают в пользовательском, непривилегированном режиме. Данная архитектура основана на подходе клиент-сервер и характеризуется переносимостью, расширяемостью и надежностью (рис. 7. в) ![]() Рис. 7. Классификация по типу архитектуры ядра Концепция системы виртуальных машин может быть поддержана экзоядром. Каждый пользователь может быть обеспечен абсолютной копией реального компьютера, но с подмножеством ресурсов. На экзоядро возложена задача распределения ресурсов для виртуальных машин и проверка использования ресурсов. Отметим, что архитектура ядра в значительной степени влияет на всю архитектуру операционной системы.» 3. ПроцессыПонятие процесса является одним из основных в современных операционных системах. В этом разделе мы рассмотрим сущность процессов и потоков. ^ 3.1.2. Понятие процесса[1]
Первое упоминание о процессе появилось в 60-е годы 20 века в операционной системе MULTICS. Если говорить о соотношении между процессом и программой ( несмотря на то, что это понятия из различных областей), то справедливы следующие два утверждения ^ . С этой точки зрения процесс – нечто большее, чем просто программа; Программа может вызывать более чем один процесс для выполнения работы. С этой точки зрения программа – нечто большее, чем процесс. Процессы образуют иерархию в операционной системе. Соответственно будем называть порожденные процессы потомками данного процесса, а родителя порожденного процесса – предком. Отметим основные состояния процесса (рис. 8.):
![]() Рис. 8. Основные состояния процесса При создании процесса должны быть выполнены следующие действия:
^ [1] «Поток (нить) управления– это исполнение команд программы в естественном порядке. Процессы делятся на традиционные - имеющие один поток управления и многопоточные (многонитевые). Многопоточность в рамках одного процесса имеет существенные преимущества. Переключение контекста между двумя потомками в одном процессе значительно проще, чем переключение контекста между двумя процессами.
Можно указать целые классы программ, где необходима многопоточность:
Потоки могут быть реализованы как в пространстве пользователя, так и в пространстве ядра.
Одна из наиболее смешанных элегантных реализаций потоков выполнена в OC Solaris. Все потоки(нити) можно разделить на три класса (рис. 9). Потоки ядра являются базовыми потоками. Они располагаются в адресном пространстве ядра и непосредственно связаны с процессами. Облегченные (легковесные) потоки служат для организации пользователем нескольких потоков управления в адресном пространстве. Каждому облегченному потоку соответствует свой отдельный ядерный поток. Каждый облегченный поток может отдельно планироваться (на каждый процессор по потоку). Облегченные потоки следует рассматривать как диспетчеризуемые сущности. Пользовательские потоки, для создания которых пользователь работает со стандартной библиотекой. Пользовательские потоки связываются с облегченными потоками.» ![]() Рис. 9. Классы потоков ^ [1] «Как правило, технику явного распараллеливания не следует использовать при прикладном программировании. Нужно переложить заботу о распараллеливании на компиляторы, возможно помогая ему директивами (например, OpenMP). Однако системному программисту знание и умение применять нити в своих программах необходимо. Многие операционные системы, ориентированные на рабочие станции, и персональные компьютеры, начиная с середины 80-х годов 20 века, включают поддержку многопоточности. Впервые стандарт на потоки появился в 1995 году. Это был стандарт IEEE POSIX 1003.1c – 1995. Однако стандарт появился достаточно поздно, и некоторые компании успели выпустить свои версии многопоточных библиотек, существенно отличающиеся от стандарта. Можно выделить следующие основные семейства потоков: 1. Потоки, поддерживающие стиль POSIX – стандарта. Это семейство состоит из трех подгрупп: «истинные» POSIX-потоки, базирующиеся на стандарте IEEE POSIX 1003.1с-1995 (также известного как ISO/IEC 9945-1:1996), являющегося частью стандарта ANSI/IEEE 1003.1; DCE – потоки, базирующиеся на ранней версии стандарта POSIX – 1003.1а Unix International –потоки, также известные как Solaris– потоки. Они достаточно близки к стандарту и поддерживаются в операционных системах Solaris компании Sun Microsystem, Inc и Unix Ware 2 компании SCO. 2. Потоки Microsoft. Это семейство состоит из двух подгрупп, причем обе разработаны в компании Microsoft:
3. Других вариантов потоков не так много. Отдельного упоминания заслуживает пакет C thread, имеющийя в операционной системе Mach. Различные семейства предлагают различный синтаксис основных функций потоковых библиотек. Основными группами функций являются функции создания потоков и функции синхронизации потоков (как правило, набор таких функций достаточно богат и разнообразен).» ^ [1] «В документации к некоторым фрагментам кода (как правило, системным функциям) стоит пометка о том, что они безопасны с точки зрения использования в многопоточных программах (MT-safe). Отсутствие подобной пометки может означать наличие в таких функциях глобальных или статических переменных, приводящих к побочным эффектам.» ^ [2]
^ Как уже было упомянуто выше, создание процесса требует определенных системных ресурсов, что неизбежно сказывается на времени работы приложения. Так как пользовательский поток создается в рамках процесса, а нить создается в рамках пользовательского потока, то все сказанное справедливо и для них. Создание параллельных конструкций (без реализации исполнения по ним участков кода программы) в выполняемой программе имеет смысл последовательного кода, и, согласно закону Амдала, неизбежно уменьшает ускорение параллельной программы. Поэтому, прежде чем организовать работу параллельной конструкции, программист должен оценить временные затраты на ее реализацию, чтобы ответить на вопрос – выгодно это будет или нет. Для оценки данных затрат используется стандартный метод – исследуемая конструкция помещается в многократно выполняемый цикл. В многопоточном программировании любому программисту необходимо знать временные затраты по созданию параллельного региона. Это можно определить из сравнения времени работы пустого цикла и цикла, содержащего директиву по созданию параллельного региона: Пустой цикл: start = clock(); for (i=0;i finish = clock(); duration_no = (finish - start); Цикл с параллельной конструкцией start = clock(); for (i=0;i #pragma omp parallel { } finish = clock(); duration_parallel = (finish - start); В результате выполнения данного теста нетрудно убедиться, что на создание параллельного региона требуются доли миллисекунды, или более, чем 1000 циклов процессора. Иногда в параллельном регионе необходимо организовать выполнение участков кода только одним потоком одновременно. Это может быт реализовано двумя различными способами: или созданием критического участка кода, который может выполнять только один поток start = clock(); #pragma omp parallel { for (i=0;i { #pragma omp critical { } } finish = clock(); или созданием «объекта синхронизации» для потоков: захватить этот объект может только один поток: omp_lock_t lsk; start = clock(); omp_init_lock(&lsk); #pragma omp parallel shared(lsk) { for (i=0;i { omp_set_lock(&lsk); { } omp_unset_lock(&lsk); } } finish = clock(); duration_mutex = (finish - start); Нетрудно убедиться, что реализация данных конструкций является также дорогостоящей операцией, хотя затраты на порядок меньше и составляют сотни циклов процессора. 6. Задание
Замечание. Для выполнения задания предлагается накладывать комментарии на лишние операторы
|