
- •Раздел 3. Параллельное выполнение программ
- •3.1. Концепция процесса
- •3.2. Средства описания параллелизма
- •3.2.1. Графические средства
- •3.2.3. Описание процессов средствами uml
- •3.2.4. Языковые средства описания параллелизма
- •3.3. Организация ядра ос
- •3.3.1. Ядро как средство организации виртуальной машины
- •3.3.2. Состояния процесса и структура ядра
- •3.3.3. Дескрипторы процессов
- •3.3.4. Очереди процессов в ядре
- •3.4. Общая характеристика примитивов ядра
- •3.5. Примитивы создания и уничтожения процессов
- •3.6. Примитивы синхронизации процессов
- •3.6.1. Простейшие примитивы, не учтенные в классификации
- •3.6.2. Примитивы временной синхронизации
- •3.6.3. Примитивы событийной синхронизации процессов
- •3.7. Общий семафор как средство событийной синхронизации
- •3.8. Средства синхронизации в существующих операционных системах
- •3.9. Монитор как средство реализации взаимного исключения
- •3.10. Примитивы ядра для обмена сообщениями
- •3.10.1. Буфер как средство коммуникации между процессами
- •3.10.2. Почтовый ящик с очередью сообщений
- •3.10.3. Средства коммуникаций в существующих ос
- •3.11. Проблема тупиков при взаимодействии процессов
- •3.12. Планирование загрузки процессора в ядре
- •3.12.1. Классификация алгоритмов планирования
- •3.12.2. Тесты планируемости задач и классификация задач
- •3.12.3. Динамическое планирование
- •3.12.3.1. Планирование независимых задач
- •1. Алгоритм монотонной скорости.
- •2. Алгоритм “задача с минимальным предельным сроком завершения - первая”
- •3. Алгоритм минимальной неопределенности
- •3.12.3.2. Планирование зависимых задач
- •3.12.4. Статическое планирование
3.2.3. Описание процессов средствами uml
Общая характеристика UML
UML – это язык для выражения конструкций и отношений сложных систем.
Он начинался как ответ на запрос Группы Объектного Моделирования на предложение о стандартизации Объектно-Ориентированной методологии.
UML более законченный механизм, чем другие методы в своей поддержке моделирования сложных систем.
Контекстные диаграммы
Построение контекстных диаграмм на этапе анализа требований к системе позволяет описать объекты, с которыми система должна взаимодействовать, события, происходящие при этом взаимодействии, и сообщения, которыми обмениваются система и внешние объекты.
Варианты использования
Диаграммы вариантов использования представляют собой одно из средств описания реакции системы на определенные внешние события и являются детализацией контекстных диаграмм, рассмотренных выше.
Сценарии
Дальнейшей детализацией вариантов использования являются сценарии. Любой отдельный вариант использования порождает множество сценариев.
Описание сценариев последовательными диаграммами
Последовательные диаграммы описывают сценарии как последовательности передаваемых и принимаемых сообщений между объектами.
Последовательные диаграммы позволяют специфицировать временные требования к сообщениям и переходы объектов из одних состояний в другие под действием сообщений.
Описание сценариев временными диаграммами
Временные диаграммы особенно полезны, когда большое значение имеют временные соотношения.
Описание сценариев диаграммами сотрудничества
Диаграмма сотрудничества показывает в основном ту же самую информацию, что и последовательная диаграмма, но акцентируется на статической структуре взаимодействующих объектов, а не на очередности сообщений или состояний.
Диаграммы объектов
После того, как определено внешнее окружение системы, необходимо внутри самой системы идентифицировать базовые объекты и их взаимоотношения.
Диаграммы классов
Объекты, которые идентичны по структуре и поведению, должны быть объединены в классы.
Диаграммы состояний
Самым важным средством описания поведения системы является описание с помощью диаграмм состояний.
Диаграммы активности
Диаграммы активности приближают нас к построению алгоритмов функционирования системы. Диаграммы активности, так же, как и диаграммы состояний, могут строиться с разной степенью детализации, иметь вложенные состояния и отражать определенные стороны функционирования системы.
Диаграммы развертывания
Диаграммы развертывания описывают физическую архитектуру системы и показывают как классы реализованы в различных компонентах кода и как результирующие выполняемые компоненты распределены по узлам (компьютерам и другим устройствам), в которых они выполняются.
3.2.4. Языковые средства описания параллелизма
В традиционно используемых языках программирования средства описания параллелизма отсутствуют, т.к. эти языки изначально создавались для последовательного программирования. Существуют два языка, в которых средства описания параллелизма существуют как стандартные.
В языке АДА существует следующее средство - если описать некоторые программные единицы как задачи - TASK, то с момента начала выполнения всей программы эти единицы начнут выполняться параллельно. Т. е. обработчик прерываний и средства замены контекста зашиты в АДЕ на уровне языка. Кроме того, АДА предлагает некоторый механизм взаимодействия задач, который называется РАНДЕВУ, тоже существующий на уровне языка.
В языке МОДУЛА-2, который весь построен на библиотечных модулях в соответствие со своим названием, есть модуль Process, который реализует временное разделение с помощью обработчика прерываний и содержит протокол и набор процедур-примитивов, позволяющий создавать из процедур параллельно выполняемые процессы и организовывать их взаимодействие. Модуль Process предлагает следующие возможные действия:
StartProcess: создать процесс;
StartScheduler: запуск планировщика задач с временным разделением;
StopScheduler: останов планировщика задач;
WAIT: ждать сигнал;
SEND: послать сигнал.
Процессы в Модуле-2 создаются из сопрограмм аналогично рассматриваемым в лабораторных работах.
Современные операционные системы предоставляют примитивы - API, позволяющие реализовывать многозадачность. Эти примитивы отличаются синтаксисом в зависимости от среды и могут трактоваться как расширения языка программирования, в точности соответствуя понятию ВЫЗОВ ПРОЦЕДУРЫ ОС.
Примеры
Вопрос (
Linux
fork() создание нового процесса. Вызывающий процесс дублируется и создается точная его копия, отличающаяся от порождающего процесса только идентификатором.
sleep(sec) приостанов процесса на sec секунд.
exit() завершение вызывающего процесса.
)Вопрос
Вопрос (
Windows
CreateProcess() создание процесса.
ExitProcess() завершение текущего процесса.
CreateThread() запуск экземпляра нити.
ExitThread() завершение работы нити.
Sleep(ms) приостанов процесса на ms миллисекунд.
)Вопрос
В каждой из перечисленных сред есть еще примитивы для работы с процессами и нитями. Это были только примеры, причем в примерах не приведены передаваемые параметры.
Существует еще набор абстрактных (не относящихся к конкретному языку программирования), но Паскале-подобных языковых конструкций, предложенных Виртом для описания параллелизма, которые мы сейчас и рассмотрим.
Нотация "and" позволяет программисту указывать предложения, которые выполняются параллельно.
Например,
(Уже не Вирт) «fork w» команда, выполненная процессом p, вызывает начало развития нового процесса q с команды, помеченной w. Далее процессы p и q развиваются одновременно.
«quit» - завершение процесса.
«join t, w» вызывает следующие действия:
---------------------
t := t - 1;
if t = 0 then goto w;
---------------------
Цель этой команды - обеспечить синхронизацию процессов, т. е. начать выполнение с метки w только после того как несколько процессов (их число определяет, в какое начальное значение инициализируется t) выполнят команду join. После нее обычно ставится команда quit. Только последний из перечисленных процессов пойдет на метку, остальные завершатся.
Пунктиром отмечен тот факт, что приведенные действия выполняются как неделимые.
Иллюстрация в виде графа
Обозначение по ГОСТ
Описание с помощью вышеприведенных языковых конструкций:
Введем переменные Т1 и Т2.
Т1 := 2; w1: P1; join T2, w5;
T2 := 2; join T1, w4; quit;
P0; quit; w4: P4;
fork w1; w2: P2; join T2, w5;
fork w2; join T1, w4; quit;
fork w3; quit; w5: P5;
quit; w3: P3; quit;
Обратим внимание на требование неделимости действий в команде join. Посмотрим, как правильно должна выполняться эта команда.
Предположим, что t = 2 и оба процесса подошли к выполнению этой команды.
--------------------- ---------------------
t := t - 1; t := t - 1;
if t = 0 then goto w; if t = 0 then goto w;
--------------------- ---------------------
quit; quit;
Если первым подойдет процесс 1, то t станет равным 1 и первый процесс перейдет к выполнению оператора quit без перехода на метку. Второй процесс сделает t, равным 0, и пойдет на метку w. Это так надо, чтобы выполнялось.
Что может произойти, если команда join не будет неделимой. Это значит, что когда первый процесс уменьшит t на 1, управление может передаться второму процессу, который тоже уменьшит t на единицу. После этого первый процесс пойдет на метку w и второй процесс пойдет на метку w, т. к. t = 0 для обоих процессов перед условным оператором. Это неправильно.