- •Тема 4: Понятия параллельного выполнения
- •4.1. Принципы параллельных вычислений
- •4.2 Параллелизм в системах аппаратного оборудования
- •4.3 Параметры многозадачной вычислительной системы
- •4.4 Параллелизм в системах программного обеспечения
- •Параллелизм в системах программного обеспечения
- •4.5 Аппаратная поддержка многозадачного режима
- •4.5.1 Переключение задач
- •Алгоритм аппаратного переключения между задачами
- •Тема 5: Организация параллельных взаимодействующих вычислений
- •5.1 Независимые и взаимодействующие вычислительные процессы
- •5.2 Средства синхронизации и связи взаимодействующих вычислительных процессов
- •5.2.1 Использование блокировки памяти при синхронизации параллельных процессов
- •5.2.2 Синхронизация процессов с помощью операций проверки и установки
- •5.2.3 Семафорные примитивы Дейкстры
- •5.2.4 Мониторы Хоара
- •5.3 Конвейеры и очереди сообщений
- •Тема 6: Планирование и диспетчеризация процессов и задач
- •6.3 Алгоритмы планирования
- •6.4 Планирование и диспетчеризация процессов и задач
- •6.3.1 Планирование вычислительных процессов и стратегии планирования
- •6.4 Дисциплины диспетчеризации
Операционная система должна распределять и освобождать различные ресурсы для
каждого активного процесса, в том числе следующие.
Процессорное время
Память: большинство ОС используют схему виртуальной памяти.
Файлы.
Устройства ввода-вывода:
3. Операционная система должна защищать данные и физические ресурсы каждого процесса от непреднамеренного воздействия других процессов, что включает использование технологий, применяющихся для работы с памятью, файлами и устройствами ввода-вывода.
4. Результат работы процесса не должен зависеть от скорости его выполнения по отношению
к другим параллельно выполняющимся процессам.
4.2 Параллелизм в системах аппаратного оборудования
Параллелизм заложен уже на уровне разрядов. Так, операция сложения чисел реализована путем параллельного сложения разрядов с учетом переноса. Команды процессора выполняются параллельно за счет использования конвейера и суперскалярности. Суперскалярнисть означает наличие нескольких блоков для параллельного выполнения операций.
К сожалению, параллельное выполнение команд возможно не всегда по следующим причинам:
последовательные команды могут быть зависимыми по результатам. Это означает, что результат выполнения последующей команды зависит от результата выполнения предыдущей команды;
команды перехода нарушают порядок выполнения команд, оттого результат выполнения следующей команды аннулируется;
современные процессоры используют специализированные блоки для целочисловых расчетов, для вычислений с плавающей точкой, для операций умножения и др.
В связи с последним недостатком в современных процессорах используется технология HYPER THREADING. Содержание этой технологии заключается в том, что параллельные устройства процессора используются не для выполнения дежурных команд одного потока, а для различных потоков одного процесса или даже различных процессов. В этом случае ОС рассматривает один физический процессор как несколько логических процессоров - ОС их использует для различных потоков. В этом случае говорят о многоядерном процессоре. Пример такого процессора - процессор ITANIUM.
Процессоры внешних устройств работают параллельно с ЦП, если одно устройство выполняет операцию ввода / вывода, а другое - вычислительные операции. Это обеспечивает параллельное выполнение нескольких операций даже на однопроцессорной системе.
В многопроцессорной системе параллельно работают все процессоры.
Определим способы осуществления многозадачности:
1. Сама задача может время от времени передавать управление другой задаче.
2. Управление может в порядке очереди отбираться у одной задачи и передаваться другой задаче.
Первый способ получил название кооперативной (не вытесненной) многозадачности, а второй, используемый в большинстве современных ОС - вытесненной многозадачности.
4.3 Параметры многозадачной вычислительной системы
Эффективность работы многозадачной вычислительной системы определяется тремя параметрами:
• пропускной способностью (количеством выполненных программ за единицу времени);
• реактивностью (временами отзыва каждой запущенной на выполнение программы);
• динамичностью (способностью обеспечивать удобство работы пользователя в динамически переменчивой обстановке).
К сожалению, эти параметры взаимно исключают один одного. Это привело к делению ОС на три типа, каждый из которых обеспечивает наилучшее значение для одного из этих параметров.
Наибольшую пропускную способность с точки зрения одной программы имеют системы пакетной обработки. В этом случае не расходуется время на сохранение и возобновление текущего состояния задачи при ее вытеснении. Однако в этом случае процессор простаивает во время выполнения операций, в которых он не участвует. Определенную часть времени своего выполнения программа расходует на операции ввода/вывода (которые, как правило, не требуют участия центрального процессора, а следовательно, могут выполняться параллельно с программой). Пока одна с программ ожидает завершения операции ввода/вывода, процессор выполняет другую программу. В итоге многозадачность обеспечивает большую пропускную способность, чем характерное для систем пакетной обработки однозадачное выполнение программ в порядке очереди.
Таким образом, наилучшими с точки зрения пропускной способности являются ОС с невытеснявшей многозадачностью.
Второй параметр - реактивность - обеспечивает время отзыва (время выполнения) программы. То есть реактивная система (такие системы называются системами реального времени), гарантирует, что программа выполнится в определенный промежуток времени.
Третий параметр - динамичность - определяет удобство работы пользователя, который желает иметь возможность работать одновременно с несколькими программами интерактивно, причем заблаговременно неизвестно, когда и с которыми. То есть алгоритмы распределения ресурсов компьютера в такой системе должны приемлемый вести себя с неизвестным предварительно количеством программ и запрошенным количеством ресурсов. Такие системы называются системами распределения времени, к ним принадлежат популярные WINDOWS, LINUX и др.
На первый взгляд кажется, что требования динамичности и реактивности похожие, но это не так. В системах реального времени предварительно известно, которые программы будут запущены и которые ресурсы им понадобятся, что позволяет самое эффективное спланировать распределение ресурсов (следовательно, гарантировать, что в любой ситуации программа будет выполнена за определенный промежуток времени). В системах распределения времени никаких предположений относительно количества и порядка запуска добавлений сделать нельзя.
4.4 Параллелизм в системах программного обеспечения
Программы, которые выполняются параллельно, или устройства, которые работают параллельно, как правило не должны знать друг о друге и не мешать одна одной. К тому же, различные устройства могут работать с различной скоростью. Исходя из этого единичный результат выполнения работы должен быть независимым и такой единицей результата является процесс. Таким образом, один с признаков процессов - независимые результаты работы, которые выполняються с различной скоростью.
Не все процессы должны быть независимыми. Возможны определенные требования взаимодействия между параллельно работающими процессами. Эти взаимодействия осуществляется по предварительно определенным правилам.
Заметим, что параллелизм может быть обеспеченный не только на уровне отдельных процессов, но и внутри процесса за счет использования языковых возможностей. Существует целая теория параллельных вычислений и их использования для решения конкретных задач. Некоторые языки программирования обеспечивают задания участков кода, которые могут выполняться параллельно. В наше время, когда многопроцессорные системы приобрели широкое применение, эта проблема становится все актуальнее.
Лекция 7
План лекции:
5. Аппаратная поддержка многозадачного режима
Алгоритм аппаратного переключения между задачами
Параллелизм в системах программного обеспечения
Литература:
М.Ф.Бондаренко, О.Г.Качко Операційні системи : навч.посібник. 2008. 432с. Стр.76 – 79
4.5 Аппаратная поддержка многозадачного режима
Когда в машине один процессор, паралельные процессы не могут перекрываться, а способны только чередоваться, поэтому многозадачность поддерживалась только на программном уровне, путем чередования процессов. Современные многопроцессорные системы аппаратно поддерживают чередование задач. Этот механизм используется для обработки прерываний и перехода между процессами.
4.5.1 Переключение задач
Задача - единица работы для процессора, то есть это единица, на которую процессор может переключиться, приостановить ее выполнение или удалить. Это может быть утилита ОС или управляющая программа.
На аппаратном уровне решаются такие проблемы:
сохранение состояния текущей задачи;
запуск задачи, начиная с начала или из точки, где ее выполнение было приостановлено.
Новая задача может быть запущенная как функция - этим обеспечивается возврат к предыдущей задаче после завершения запущенной (команда CALL). Можно запустить новую задачу без сохранения адреса возврата (команда JMP). Аппаратные средства перехода между задачами могут использоваться и часто используются ОС для поддержки механизма перехода между приложениями в случае многопрограммного режима.
В дальнейшем будем называть старой задачу, которая инициирует переход, а новой будем называть задачу, на которую выполняется переход. Схема переключения между задачами посредством команд JMP и CALL представлена на рис. 4.1
С тарая задача JMP Новая задача
С тарая задача CALL Новая задача
Рис. 4.1- Переключение между задачами посредством команд JMP и CALL
Для переключения задач используются такие структуры данных.
• сегмент состояния задачи (Task Status Segment - TSS);
• дескриптор сегмента состояния задачи (Task Status Segment Descriptor - TSSD);
• регистр задачи (Task Register - 77?);
• дескриптор шлюза задачи (Task Gate Descriptor);
• NT-флаг в регистре EFLAGS.
Сегмент состояния задачи (TSS)
Используется для сохранения состояния задачи с целью обеспечения возможности продолжения ее выполнения.
Все поля сегмента состояния задачи разделяются на статические и динамические. Статические поля формируются при создании задачи и остаются без изменения вплоть до ее завершения. Состояние динамических полей изменяется в процессе переключения.
Минимальный размер TSS равняется 104 байтам, то есть при переходе между задачами необходимо сохранить и потом возобновить, по меньшей мере, 104 байтов. Учитывая это переход между задачами является сложной операцией. Переключение между задачами происходит, если:
1. В командах call, jmp задан селектор для TSS или селектор для шлюза TSS - явное переключение.
2. Выполняется переход на обработчик прерываний или исключений - неявное переключение.
3. Выполняется команда iret после завершения задачи, вызванной командой call (то есть установлен флажок вложенности задач NT в EFLAGS).
Дескриптор TSS
Сегмент состояния задачи, как и все другие сегменты, определяется дескриптором. Дескриптор TSS задается в GDT и представляет собой пример системного дескриптора. Минимальный размер TSS при условии отсутствия карты разрешения ввода/вывода и дополнительной информации равняется 104 байтам. Если граница сегмента меньше 103, то при переходе на такую задачу генерируется отказ на выполнение.
Заметим, что сегмент TSS имеет особые права доступа. Право осуществлять чтение/запись в этот сегмент имеет только процессор. Пользователю с любым уровнем привилегий в этот сегмент не только нельзя записать какую-либо информацию, но даже прочитать ее.
Регистр задачи
Регистр задачи (Task Register - TR) содержит информацию о текущей задаче, которая состоит из двух частей: «видимой» и «невидимой». «Видимая» часть может считываться и изменяться программным обеспечением. «Невидима» часть используется процессором. В видимой части есть селектор для TSS, что содержит индекс TSS в GDT. Процессор использует невидимую часть для записи адреса начала и границы дескриптора TSS. Сохранение в регистре этих значений делает выполнение задачи более эффективным, поскольку для ссылки к TSS текущей задаче процессору не нужно добывать эти значения с памяти.
Шлюз задачи
Используется для защищенного переключения между задачами. В шлюзе задается информация о TSS и переключение между задачами происходит по команде перехода, где задается адрес TSS.
NT-флаг в регистре EFLAGS
Поскольку переключение между задачами происходит только в два способа: по команде JMP без возвращения в область старой задачи и по команде CALL с возможностью возвращения. Но есть способ возвращения с помощью установки в регистре флагов выполняемой задачи бита NT, что означает, что по завершении новой задачи необходимо вернуться к выполнению старой.
Алгоритм аппаратного переключения между задачами
Алгоритм содержит в себе такие пункты.
Из операнда команды JMR или CALL процессор получает селектор, который указывает на TSS или шлюз TSS.
Процессор проверяет наличие полномочий старой задачи для переключения задач.
Процессор проверяет наличие в памяти TSS новой задачи и его размер (минимально допустимый — не меньше 103).
Процессор проверяет доступность новой задачи (она не должна быть занятой -флажок BUSY сброшен).
Если для переключения задач используется команда JMP, флажок BUSY для старой задачи сбрасывается. Если используется команда IRET, флажок BUSY переписывается в копии регистра EFLAG.
Выбирается адрес TSS для текущей (старой) задачи из регистра задачи, и туда записываются все динамические поля, в том числе содержание регистра ЕIР, который определяет адрес дежурной команды в прерванной задаче.
Если для переключения задач используется команда CALL, в образе регистра EFLAGS в стеке устанавливается флажок вложенности задач (NT). Если используется команда IRET, флажок NT в образе регистра EFLAGS в стеке сбрасывается.
Для новой задачи, которая инициирована командами CALL, JMP, устанавливается флажок занятости BUSY в дескрипторе TSS этой задачи.
Устанавливается флаг TS в образе регистра CR0 в TSS этой задачи. Бит TS полезный системным программам для координации работы целочислового блока и блока операций с плавающей точкой. Бит TS указывает на то, что содержание блока операций с плавающей точкой может отличаться от соответствующего содержания для текущей задачи.
Загружается регистр задач TR, что теперь должен указывать на TSS новой задачи.
Загружаются все регистры с TSS этой задачи, в том числе CR3, благодаря чему будет использован виртуальный адресный простор новой задачи, ЕIР, то есть следующей будет выполнена команда новой задачи.
Если при выполнении какого-то пункта алгоритма произошла ошибка, алгоритм завершается.
Многозадачный режим для многопроцессорной системы
В наше время многопроцессорные системы получили значительное распространение. Требование относительно эффективной поддержки многопроцессорного режима является одним из важнейших для современных ОС.
Рассмотрим аппаратную поддержку этого требования. Допустим, что все процессоры, включенные в систему, одинаковые. Такие многопроцессорные системы называются симметричными. Наряду с такими процессорами в системе используются специализированные процессоры (графические, видео, для обеспечения связи и др.). Все эти процессоры используют одну общую системную шину.
Основные трудности, которые необходимо преодолеть в данном случае — это синхронизация работы процессоров и обеспечения высокопродуктивного доступа к памяти. В частности, задача синхронизации встает, если два (или больше) процессора одновременно пытается получить доступ к одной ячейки памяти. Задача высокопродуктивного доступа к памяти решается посредством кэша, но в этом случае один процессор может обращаться к данным, которые находятся в кэш-памяти другого процессора, в этом случае возникает проблема доступа к достоверным данным..
Лекция 8
Тема 5: Организация параллельных взаимодействующих вычислений
План лекции:
Независимые и взаимодействующие вычислительные процессы.
Средства синхронизации и связи взаимодействующих вычислительных процессов
Литература:
А.В.Гордеев Операционные системы : учебник. 2007. 416с. Стр.209 –246
Мультипрограммные и мультизадачные операционные системы позволяют организовать не только независимые, но взаимодействующие вычисления. Сама операционная система как комплекс управляющих и обрабатывающих программных модулей также функционирует как множество взаимодействующих вычислений. Проблема синхронизации взаимодействия параллельных вычислительных процессов, обмена данными между ними является одной из важнейших. Существующие методы синхронизации вычислений и обмена сообщениями различаются по таким параметрам, как удобство программирования параллельных процессов, стоимость реализации, эффективность функционирования созданных приложений и всей вычислительной системы в целом. Операционные системы имеют в своем составе различные средства синхронизации. Знание этих средств и их правильное использование позволяет создавать программы, которые при работе осуществляют корректный обмен информацией, а также исключают возможность возникновения тупиковых ситуаций.
5.1 Независимые и взаимодействующие вычислительные процессы
Основной особенностью мультипрограммных операционных систем является то, что в их среде параллельно развивается несколько (последовательных) вычислительных процессов. С точки зрения внешнего наблюдателя эти последовательные вычислительные процессы выполняются одновременно, мы же будем говорить «параллельно». При этом под параллельными понимаются не только процессы, одновременно развивающиеся на различных процессорах, каналах и устройствах ввода-вывода, но и те последовательные процессы, которые разделяют центральный процессор и в своем выполнении хотя бы частично перекрываются во времени.
Любая мультизадачная операционная система вместе с параллельно выполняющимися в ней задачами может быть логически представлена как совокупность последовательных вычислений, которые, с одной стороны, состязаются за ресурсы, переходя из одного состояния в другое, а с другой — действуют почти независимо один от другого, но при этом образуя единую систему посредством установления разного рода связей между собой (путем пересылки сообщений и синхронизирующих сигналов).
Итак, параллельными мы будем называть такие последовательные вычислительные процессы, которые одновременно находятся в каком-нибудь активном состоянии.
Два параллельных процесса могут быть независимыми (independed processes) либо взаимодействующими (cooperating processes).
Независимыми являются процессы, множества переменных которых не пересекаются. Под переменными в этом случае понимают файлы данных, а также области оперативной памяти, сопоставленные промежуточным и определенным в программе переменным. Независимые процессы не влияют на результаты работы друг друга, так как не могут изменять значения переменных друг у друга. Они могут только явиться причиной в задержках исполнения друг друга, так как вынуждены разделять ресурсы системы.
Взаимодействующие процессы совместно используют некоторые (общие) переменные, и выполнение одного процесса может повлиять на выполнение другого. Как мы уже говорили, при выполнении вычислительные процессы разделяют ресурсы системы. Подчеркнем, что при рассмотрении вопросов синхронизации вычислительных процессов из числа разделяемых ими ресурсов исключаются центральный процессор и программы, реализующие эти процессы, то есть с логической точки зрения каждому процессу соответствуют свои процессор и программа, хотя в реальных системах обычно несколько процессов разделяют один процессор и одну или несколько программ. Многие ресурсы вычислительной системы могут совместно использоваться несколькими процессами, но в каждый момент времени к разделяемому ресурсу может иметь доступ только один процесс. Ресурсы, которые не допускают одновременного использования несколькими процессами, называются критическими. Если несколько вычислительных процессов хотят пользоваться критическим ресурсом в режиме разделения, им следует синхронизировать свои действия таким образом, чтобы ресурс всегда находился в распоряжении не более чем одного из них. Если один процесс пользуется в данный момент критическим ресурсом, то все остальные процессы, которым нужен этот ресурс, должны ждать, пока он не освободится. Если в операционной системе не предусмотрена защита от одновременного доступа процессов к критическим ресурсам, в ней могут возникать ошибки, которые трудно обнаружить и исправить. Основной причиной возникновения этих ошибок является то, что процессы в мультипрограммных операционных системах развиваются с различными скоростями и относительные скорости развития каждого из взаимодействующих процессов не подвластны и не известны ни одному из них. Более того, на их скорости могут влиять решения планировщиков, касающиеся других процессов, с которыми ни одна из этих программ не взаимодействует. Кроме того, содержание и скорость исполнения одного из них обычно не известны другому процессу. Поэтому влияние, которое оказывают друг на друга взаимодействующие процессы, не всегда предсказуемо и воспроизводимо. Взаимодействовать могут либо конкурирующие процессы, либо процессы, обрабатывающие информацию совместно. Конкурирующие процессы действуют относительно независимо друг от друга, однако они имеют доступ к некоторым общим переменным. Их независимость заключается в том, что они могут работать друг без друга, поодиночке. Но при своем выполнении они могут работать и параллельно, и тогда они иногда начинают конкурировать при обращении к этим общим переменным. Таким образом, их независимость относительна.
Приведем несколько наиболее известных примеров конкурирующих процессов и продемонстрируем появление ошибок.
В качестве первого примера рассмотрим работу двух процессов Р1 и Р2 с общей переменной X. Пусть оба процесса асинхронно, независимо один от другого, изменяют (например, увеличивают) значение переменной X, считывая ее значение в локальную область памяти Ri1, при этом каждый процесс выполняет во времени некоторые последовательности операций (табл. 5.1). Здесь мы рассмотрим не все операторы каждого из процессов, а только те, в которых осуществляется работа с общей переменной X. Каждому из операторов мы присвоили некоторый условный номер.
Таблица 5.1. Пример конкурирующих процессов
Номер оператора |
Процесс Р1 |
Номер оператора |
Процесс Р2 |
1 |
R1: = Х |
4 |
R2: = X |
2 |
R1: = R1 + 1 |
5 |
R2: = R2 + 1 |
3 |
X: = R1 |
6 |
X: = R2 |
Поскольку при мультипрограммировании процессы могут иметь различные скорости исполнения, то может иметь место любая последовательность выполнения операций во времени. Например, если сначала будут выполнены все операции процесса Р1, а уже потом — все операции процесса Р2 (рис. 5.1) или, наоборот, сначала — операции 4-6, а затем — операции 1-3, то в итоге переменная X получит значение, равное X + 2
Р1: (1)R1:=X; (2) R1:=R1+1; (3) X:=R1;
Р2: (4) R2:=X; (5) R2:=R2+1; (6)X:=R2;
----------------------► Время
Рис. 5.1. Первый вариант развития событий при выполнении процессов
Однако если в промежуток времени между выполнением операций 1 и 3 будет выполнена хотя бы одна из операций 4-6 (рис. 5.2), то значение переменной X после выполнения всех операций будет не (X + 2), а (X + 1).
Р1: (1) R1 :=Х; (2)R1:=R1+1; (3)X:=R1;
Р2: (4) R2:=X; (5)R2:=R2+1; (6)X:=R2;
►Время
Рис. 5.2. Второй вариант развития событий при выполнении процессов
Понятно, что это очень серьезная ошибка. Например, если бы процессы Р1 и Р2 осуществляли продажу билетов и переменная X фиксировала количество уже проданных, то в результате некорректного взаимодействия было бы продано несколько билетов на одно и то же место. К сожалению, такого рода ошибки трудноуловимы, поскольку они иногда возникают, иногда нет.
В качестве второго примера рассмотрим ситуацию, которая еще совсем недавно была достаточно актуальной для первых персональных компьютеров. Пусть на персональном компьютере с простейшей однопрограммной операционной системой (типа MS DOS) установлена некоторая резидентная программа с условным названием TIME, которая по нажатию комбинации клавиш (например, Ctrl+T) воспроизводит на экране дисплея время в виде 18:20:59, и допустим, что значения переменных, обозначающих час, минуты и секунды, равны 18,20 и 59 соответственно, причем вывод на дисплей осуществляется справа налево (сначала секунды, затем минуты и, наконец, часы). Пусть сразу же после передачи программой TIME на дисплей информации «59 секунд» генерируется прерывание от таймера, и значение времени обновляется: 18:21:00.
После этого программа TIME, прерванная таймером, продолжит свое выполнение, и на дисплей будут выданы значения: минуты (21), часы (18). В итоге на экране мы увидим: 18:21:59.
Рассмотрим теперь несколько иной случай развития событий обновления значений времени по сигналу таймера. Если программа ведения системных часов после вычислений количества секунд 59 + 1 = 60 и замены его на 00 прерывается от нажатия клавиш Ctrl+T, то есть программа не успевает осуществить пересчет количества минут, то время, индицируемое на дисплее, станет равным 18:20:00. И в этом случае мы получим неверное значение времени.
Наконец, в качестве третьего примера приведем пару процессов, которые изменяют различные поля записей служащих какого-либо предприятия. Пусть процесс АДРЕС изменяет домашний адрес служащего, а процесс СТАТУС — его должность и зарплату. Пусть каждый процесс для выполнения своей функции копирует всю запись СЛУЖАЩИЙ в свою рабочую область. Предположим, что каждый процесс должен обработать некоторую запись ИВАНОВ. Предположим также, что после того как процесс АДРЕС скопировал запись ИВАНОВ в свою рабочую область, но до того как он записал скорректированную запись обратно, процесс СТАТУС скопировал первоначальную запись ИВАНОВ в свою рабочую область.
Изменения, выполненные тем из процессов, который первым запишет скорректированную запись назад в файл СЛУЖАЩИЕ, будут утеряны, и, возможно, никто об этом не узнает.
Чтобы предотвратить некорректное исполнение конкурирующих процессов вследствие нерегламентированного доступа к разделяемым переменным, необходимо ввести понятие взаимного исключения, согласно которому два процесса не должны одновременно обращаться к разделяемым переменным.
Процессы, выполняющие общую совместную работу таким образом, что результаты вычислений одного процесса в явном виде передаются другому, то есть они обмениваются данными и именно на этом построена их работа, называются сотрудничающими. Взаимодействие сотрудничающих процессов удобнее всего рассматривать в схеме производитель-потребитель (produces-consumer), или, как часто говорят, поставщик-потребитель.
Кроме реализации в операционной системе средств, организующих взаимное исключение и, тем самым, регулирующих доступ процессов к критическим ресурсам, в ней должны быть предусмотрены средства, синхронизирующие работу взаимодействующих процессов. Другими словами, процессы должны обращаться друг к другу не только ради синхронизации с целью взаимного исключения при обращении к критическим ресурсам, но и ради обмена данными. Допустим, что «поставщик» — это процесс, который отправляет порции информации (сообщения) другому процессу, имя которого — «потребитель». Например, некоторая задача пользователя, порождающая данные для вывода их на печать, может выступать как поставщик, а системный процесс, который выводит эти строки на устройство печати, — как потребитель. Один из методов, применяемых при передаче сообщений, состоит в том, что заводится пул (pool)2 свободных буферов, каждый из которых может содержать одно сообщение. Заметим, что длина сообщения может быть произвольной, но ограниченной размером буфера.
В этом случае между процессами «поставщик» и «потребитель» будем иметь очередь заполненных буферов, содержащих сообщения. Когда поставщик хочет послать очередное сообщение, он добавляет в конец этой очереди еще один буфер. Потребитель, чтобы получить сообщение, забирает из очереди буфер, который стоит в ее начале. Такое решение, хотя и кажется тривиальным, требует, чтобы поставщик и потребитель синхронизировали свои действия.
Например, они должны следить за количеством свободных и заполненных буферов. Поставщик может передавать сообщения только до тех пор, пока имеются свободные буферы. Аналогично, потребитель может получать сообщения, только если очередь не пуста. Ясно, что для учета заполненных и свободных буферов нужны разделяемые переменные, поэтому, так же как и для конкурирующих процессов, для сотрудничающих процессов тоже возникает необходимость во взаимном исключении. Таким образом, до окончания обращения одной задачи к общим переменным следует исключить возможность обращения к ним другой задачи. Эта ситуация и называется взаимным исключением. Другими словами, при организации различного рода взаимодействующих процессов приходится организовывать взаимное исключение и решать проблему корректного доступа к общим переменным (критическим ресурсам). Те места в программах, в которых происходит обращение к критическим ресурсам, называются критическими секциями (Critical Section, CS). Решение проблемы заключается в организации такого доступа к критическому ресурсу, при котором только одному процессу разрешается входить в критическую секцию. Данная задача только на первый взгляд кажется простой, ибо критическая секция, вообще говоря, не является последовательностью операторов программы, а является процессом, то есть последовательностью действий, которые выполняются этими операторами. Другими словами, несколько процессов могут выполнять критические секции, использующие одну и ту же последовательность операторов программы.
Когда какой-либо процесс находится в своей критической секции, другие процессы могут, конечно, продолжать свое исполнение, но без входа в их критические секции. Взаимное исключение необходимо только в том случае, когда процессы обращаются к разделяемым (общим) данным. Если же они выполняют операции, которые не ведут к конфликтным ситуациям, процессы должны иметь возможность работать параллельно. Когда процесс выходит из своей критической секции, то одному из остальных процессов, ожидающих входа в свои критические секции, должно быть разрешено продолжить работу (если в этот момент действительно есть процесс в состоянии ожидания входа в свою критическую секцию).
Обеспечение взаимного исключения является одной из ключевых проблем параллельного программирования. При этом можно перечислить требования к критическим секциям.
В любой момент времени только один процесс должен находиться в своей критической секции.
Ни один процесс не должен бесконечно долго находиться в своей критической секции.
Ни один процесс не должен бесконечно долго ожидать разрешение на вход в свою критическую секцию. В частности:
никакой процесс, бесконечно долго находящийся вне своей критической секции (что допустимо), не должен задерживать выполнение других процессов, ожидающих входа в свои критические секции (другими словами, процесс, работающий вне своей критической секции, не должен блокировать критическую секцию другого процесса);
если два процесса хотят войти в свои критические секции, то принятие решения о том, кто первым войдет в критическую секцию, не должно быть бесконечно долгим.
Если процесс, находящийся в своей критической секции, завершается естественным или аварийным путем, то режим взаимного исключения должен быть отменен, с тем чтобы другие процессы получили возможность входить в свои критические секции. Было предложено несколько способов решения этой проблемы: программных и аппаратных; локальных низкоуровневых и глобальных высокоуровневых; предусматривающих свободное взаимодействие между процессами и требующих строгого соблюдения протоколов.
Лекция 9
План лекции:
Средства синхронизации и связи взаимодействующих вычислительных процессов.
Блокировка памяти
Синхронизация процессов с помощью операций проверки и установки
Семафорные примитивы Дейкстры
3.4 Мониторы Хоара
Литература:
А.В.Гордеев Операционные системы : учебник. 2007. 416с. Стр.209 –246
5.2 Средства синхронизации и связи взаимодействующих вычислительных процессов
Все известные средства решения проблемы взаимного исключения основаны на использовании специально введенных аппаратных возможностей. К этим аппаратным возможностям относятся:
-блокировка памяти,
-специальные команды типа «проверка и установка»
-и механизмы управления системой прерываний, которые позволяют организовать такие средства, как семафорные операции, мониторы, почтовые ящики и др.
С помощью перечисленных средств можно разрабатывать взаимодействующие процессы, при исполнении которых будут корректно решаться все задачи, связанные с проблемой критических секций. Рассмотрим эти средства в следующем порядке по мере их усложнения, перехода к функциям операционной системы и увеличения предоставляемых ими удобств, опираясь на уже древнюю, но все же еще достаточно актуальную работу Дейкстры [10]. Заметим, что этот материал позволяет в полной мере осознать проблемы, возникающие при организации параллельных взаимодействующих вычислений. Эта работа Дейкстры полезна, прежде всего, с методической точки зрения, поскольку она позволяет понять наиболее тонкие моменты в этой проблематике.
5.2.1 Использование блокировки памяти при синхронизации параллельных процессов
Все вычислительные машины и системы (в том числе и с многопортовыми блоками оперативной памяти) имеют средство для организации взаимного исключения, называемое блокировкой памяти.
Блокировка памяти запрещает одновременное исполнение двух (и более) команд, которые обращаются к одной и той же ячейке памяти.
Блокировка памяти имеет место всегда, то есть это обязательное условие функционирования компьютера. Соответственно, поскольку в некоторой ячейке памяти хранится значение разделяемой переменной, то получить доступ к ней может только один процесс, несмотря на возможное совмещение выполнения команд во времени на различных процессорах (или на одном процессоре, но с конвейерной организацией параллельного выполнения команд). Механизм блокировки памяти предотвращает одновременный доступ к разделяемой переменной, но не предотвращает чередование доступа. Таким образом, если критические секции исчерпываются одной командой обращения к памяти, данное средство может быть достаточным для непосредственной реализации взаимного исключения. Если же критические секции требуют более одного обращения к памяти, то задача становится сложной, но алгоритмически разрешимой.
5.2.2 Синхронизация процессов с помощью операций проверки и установки
Операция проверки и установки является, так же как и блокировка памяти, одним из аппаратных средств, которые могут быть использованы для решения задачи взаимного исключения при выполнении критической секции. Данная операция реализована во многих компьютерах. Так, в знаменитой машине IBM 360 (370) эта команда называлась TS (Test and Set — проверка и установка).
Команда TS является двухадресной (двухоперандной). Ее действие заключается в том, что процессор присваивает значение второго операнда первому, после чего второму операнду присваивается значение, равное единице. Команда TS является неделимой операцией, то есть между ее началом и концом не могут выполняться никакие другие команды.
Чтобы использовать команду TS для решения проблемы критической секции, свяжем с ней некоторую переменную П1, которая будет общей для всех процессов, использующих некоторый критический ресурс. Данная переменная будет принимать единичное значение, если какой-либо из взаимодействующих процессов находится в своей критической секции.
Кроме того, с каждым процессом свяжем свою локальную переменную, которая принимает значение, равное единице, если данный процесс хочет войти в свою критическую секцию.
Основной недостаток использования команд типа проверки и установки состоит в следующем: находясь в цикле проверки переменной common, процессы впустую потребляют время центрального процессора и другие ресурсы.
В микропроцессорах архитектуры ia32, с которыми мы теперь сталкиваемся постоянно, работая на персональных компьютерах, имеются специальные команды ВТС, BTS, BTR, которые как раз и являются вариантами реализации команды проверки и установки.
5.2.3 Семафорные примитивы Дейкстры
Понятие семафорных механизмов было введено Дейкстрой.
Семафор (semaphore) — это переменная специального типа, которая доступна параллельным процессам только для двух операций — закрытия и открытия, названных соответственно операциями Р и V3.
Эти операции являются примитивами относительно семафора, который указывается в качестве параметра операций. Здесь семафор играет роль вспомогательного критического ресурса, так как операции Р и V неделимы при своем выполнении и взаимно исключают друг друга.
Семафорный механизм работает по схеме, в которой сначала исследуется состояние критического ресурса, идентифицируемое значением семафора, а затем уже осуществляется допуск к критическому ресурсу или отказ от него на некоторое время. При отказе доступа к критическому ресурсу используется режим пассивного ожидания. Поэтому в состав механизма включаются средства формирования обслуживания очереди ожидающих процессов. Эти средства реализуются супервизором операционной системы. Необходимо отметить, что в силу взаимного исключения примитивов попытка в различных параллельных процессах одновремено выполнить примитив над одним и тем же семафором приведет к тому, что он окажется успешной только для одного процесса. Все остальные процессы на время выполнения примитива будут взаимно исключены.
Основным достоинством семафорных операций является отсутствие состояния активного ожидания, что может существенно повысить эффективность работы мультизадачной системы.
В настоящее время на практике используется много различных видов семафорных механизмов. Варьируемыми параметрами, которые отличают различные виды примитивов, являются начальное значение и диапазон изменения значения семафора, логика действий семафорных операций, количество семафоров, доступных для обработки при исполнении отдельного примитива. Обобщенный смысл примитива P(S) состоит в проверке текущего значения семафора S. Если оно не меньше нуля, то осуществляется переход к следующей за примитивом операции. В противном случае процесс снимается на некоторое время с выполнения и переводится в состояние пассивного ожидания. Находясь в списке заблокированных, ожидающий процесс не проверяет семафор непрерывно, как в случае активного ожидания. Вместо него процессор может исполнять другой процесс, реально выполняющий какую-то полезную работу.
5.2.4 Мониторы Хоара
Анализ рассмотренных задач показывает, что, несмотря на очевидные достоинства (простота, независимость от количества процессов, отсутствие активного ожидания), семафорные механизмы имеют и ряд недостатков. Эти механизмы являются слишком примитивными, так как семафор не указывает непосредственно на синхронизирующее условие, с которым он связан, или на критический ресурс. Поэтому при построении сложных схем синхронизации алгоритмы решения задач порой получаются весьма непростыми, ненаглядными и трудными для доказательства их правильности.
Необходимо иметь очевидные решения, которые позволят прикладным программистам без лишних усилий, связанных с доказательством правильности алгоритмов и отслеживанием большого числа взаимосвязанных объектов, создавать параллельные взаимодействующие программы. К таким решениям можно отнести так называемые мониторы, предложенные Хоаром.
В параллельном программировании монитор — это пассивный набор разделяемых переменных и повторно входимых процедур доступа к ним, которым процессы пользуются в режиме разделения, причем в каждый момент им может пользоваться только один процесс.
Рассмотрим, например, некоторый ресурс, который разделяется между процессами каким-либо планировщиком. Каждый раз, когда процесс желает получить в свое распоряжение какие-то ресурсы, он должен обратиться к программе-планировщику. Этот планировщик должен иметь переменные, с помощью которых можно отслеживать, занят ресурс или свободен. Процедуру планировщика разделяют все процессы, и каждый процесс может в любой момент захотеть обратиться к планировщику. Но планировщик не в состоянии обслуживать более одного процесса одновременно. Такая процедура-планировщик и представляет собой пример монитора.
Таким образом, монитор — это механизм организации параллелизма, который содержит как данные, так и процедуры, необходимые для динамического распределения конкретного общего ресурса или группы общих ресурсов. Процесс, желающий получить доступ к разделяемым переменным, должен обратиться к монитору, который либо предоставит доступ, либо откажет в нем. Необходимость входа в монитор с обращением к какой-либо его процедуре (например, с запросом на выделение требуемого ресурса) может возникать у многих процессов. Однако вход в монитор находится под жестким контролем — здесь осуществляется взаимное исключение процессов, так что в каждый момент времени только одному процессу разрешается войти в монитор. Процессам, которые хотят войти в монитор, когда он уже занят, приходится ждать, причем режимом ожидания автоматически управляет сам монитор. При отказе в доступе монитор блокирует обратившийся к нему процесс и определяет условие ожидания. Проверка условия выполняется самим монитором, который и деблокирует ожидающий процесс. Поскольку механизм монитора гарантирует взаимное исключение процессов, исключаются серьезные проблемы, связанные с организацией параллельных взаимодействующих процессов.
Внутренние данные монитора могут быть либо глобальными (относящимися ко всем процедурам монитора), либо локальными (относящимися только к одной конкретной процедуре). Ко всем этим данным можно обращаться только изнутри монитора; процессы, находящиеся вне монитора и, по существу, только вызывающие его процедуры, просто не могут получить доступ к данным монитора. При первом обращении монитор присваивает своим переменным начальные значения. При каждом последующем обращении используются те значения переменных, которые остались от предыдущего обращения.
Если процесс обращается к некоторой процедуре монитора, а соответствующий ресурс уже занят, эта процедура выдает команду ожидания WAIT с указанием условия ожидания. Процесс мог бы оставаться внутри монитора, однако, если в монитор затем войдет другой процесс, это будет противоречить принципу взаимного исключения. Поэтому процесс, переводящийся в режим ожидания, должен вне монитора ждать того момента, когда необходимый ему ресурс освободится. Со временем процесс, который занимал данный ресурс, обратится к монитору, чтобы возвратить ресурс системе. Соответствующая процедура монитора при этом может просто принять уведомление о возвращении ресурса, а затем ждать, пока не поступит запрос от другого процесса, которому потребуется этот ресурс. Однако может оказаться, что уже имеются процессы, ожидающие освобождения данного ресурса. В этом случае монитор выполняет команду извещения (сигнализации) SIGNAL, чтобы один из ожидающих процессов мог получить данный ресурс и покинуть монитор. Если процесс сигнализирует о возвращении (иногда называемом освобождением) ресурса и в это время нет процессов, ожидающих данного ресурса, то подобное оповещение не вызывает никаких других последствий, кроме того, что монитор, естественно, вновь внесет ресурс в список свободных. Очевидно, что процесс, ожидающий освобождения некоторого ресурса, должен находиться вне монитора, чтобы другой процесс имел возможность войти в монитор и возвратить ему этот ресурс.
Чтобы гарантировать, что процесс, находящийся в ожидании некоторого ресурса, со временем получит этот ресурс, считается, что ожидающий процесс имеет более высокий приоритет, чем новый процесс, пытающийся войти в монитор. В противном случае новый процесс мог бы перехватить ожидаемый ресурс до того, как ожидающий процесс вновь войдет в монитор. Если допустить многократное повторение подобной нежелательной ситуации, то ожидающий процесс мог бы откладываться бесконечно. Для систем реального времени можно допустить использование дисциплины обслуживания на основе абсолютных или динамически изменяемых приоритетов.
Единственный ресурс динамически запрашивается и освобождается процессами, которые обращаются к процедурам REQUEST (запрос) и RELEASE (освободить). Если процесс обращается к процедуре REQUEST в тот момент, когда ресурс используется, значение переменной busy (занято) будет равно true, и процедура REQUEST выполнит операцию монитора WAIT(free). Эта операция блокирует не процедуру REQUEST, а обратившийся к ней процесс, который помещается в конец очереди процессов, ожидающих, пока не будет выполнено условие free (свободно).
Когда процесс, использующий ресурс, обращается к процедуре RELEASE, операция монитора SIGNAL деблокирует процесс, находящийся в начале очереди, не позволяя исполняться никакой другой процедуре внутри того же монитора. Этот деблокированный процесс будет готов возобновить исполнение процедуры REQUEST сразу же после операции WAIT(free), которая его и блокировала. Если операция SIGNAL(free) выполняется в то время, когда нет процесса, ожидающего условия free, то никаких действий не выполняется.
Использование монитора в качестве основного средства синхронизации и связи освобождает процессы от необходимости явно разделять между собой информацию. Напротив, доступ к разделяемым переменным всегда ограничен телом монитора, и, поскольку мониторы входят в состав ядра операционной системы, разделяемые переменные становятся системными переменными. Это автоматически исключает необходимость в критических секциях (так как в каждый момент монитором может пользоваться только один процесс, то два процесса никогда не смогут получить доступ к разделяемым переменным одновременно).
Монитор является пассивным объектом в том смысле, что это не процесс; его процедуры выполняются только по требованию процесса.
Хотя по сравнению с семафорами мониторы не представляют собой существенно более мощного инструмента для организации параллельных взаимодействующих вычислительных процессов, у них есть некоторые преимущества перед более примитивными синхронизирующими средствами.
Во-первых, мониторы очень гибки. В форме мониторов можно реализовать не только семафоры, но и многие другие синхронизирующие операции.
Во-вторых, локализация всех разделяемых переменных внутри тела монитора позволяет избавиться от малопонятных конструкций в синхронизируемых процессах — сложные взаимодействия процессов можно синхронизировать наглядным образом.
В-третьих, мониторы дают процессам возможность совместно использовать программные модули, представляющие собой критические секции. Если несколько процессов совместно используют ресурс и работают с ним совершенно одинаково, то в мониторе достаточно только одной процедуры, тогда как решение с семафорами требует, чтобы в каждом процессе имелся собственный экземпляр критической секции. Таким образом, мониторы по сравнению с семафорами позволяют значительно упростить организацию взаимодействующих вычислительных процессов и дают большую наглядность при совсем незначительной потере в эффективности.
Лекция 10
План лекции:
Почтовые ящики
Конвейеры и очереди сообщений
Литература:
А.В.Гордеев Операционные системы : учебник. 2007. 416с. Стр.209 –246
5.2 Почтовые ящики
Тесное взаимодействие между процессами предполагает не только синхронизацию — обмен временными сигналами, но также передачу и получение произвольных данных, то есть обмен сообщениями. В системе с одним процессором посылающий и получающий процессы не могут работать одновременно. В мультипроцессорных системах также нет никакой гарантии их одновременного исполнения. Следовательно, для хранения посланного, но еще не полученного сообщения необходимо место. Оно называется буфером сообщений, или почтовым ящиком
Если процесс Р1 хочет общаться с процессом Р2, то Р1 просит систему предоставить или образовать почтовый ящик, который свяжет эти два процесса так, чтобы они могли передавать друг другу сообщения. Для того чтобы послать процессу Р2 какое-то сообщение, процесс Р1 просто помещает это сообщение в почтовый ящик, откуда процесс Р2 может его в любое время получить. При применении почтового ящика процесс Р2 в конце концов обязательно получит сообщение, когда обратится за ним (если вообще обратится). Естественно, что процесс Р2 должен знать о существовании почтового ящика.
Поскольку в системе может быть много почтовых ящиков, необходимо обеспечить доступ процессу к конкретному почтовому ящику. Почтовые ящики являются системными объектами, и для пользования таким объектом необходимо получить его у операционной системы, что осуществляется с помощью соответствующих запросов.
Если объем передаваемых данных велик, то эффективнее не передавать их непосредственно, а отправлять в почтовый ящик сообщение, информирующее процесс- получатель о том, где можно их найти.
Почтовый ящик может быть связан с парой процессов, только с отправителем, только с получателем, или его можно получить из множества почтовых ящиков, которые используют все или несколько процессов. Почтовый ящик, связанный с процессом-получателем, облегчает посылку сообщений от нескольких процессов в фиксированный пункт назначения. Если почтовый ящик не связан жестко с процессами, то сообщение должно содержать идентификаторы и процесса – отправителя и процесса – получателя.
Итак, почтовый ящик — это информационная структура, поддерживаемая операционной системой. Она состоит из головного элемента, в котором находится информация о данном почтовом ящике, и нескольких буферов (гнезд), в которые помещают сообщения. Размер каждого буфера и их количество обычно задаются при образовании почтового ящика.
Основные достоинства почтовых ящиков:
процессу не нужно знать о существовании других процессов до тех пор, пока он не получит сообщения от них;
два процесса могут обменяться более чем одним сообщением за один раз;
операционная система может гарантировать, что никакой иной процесс не вмешается во взаимодействие процессов, ведущих между собой «переписку»;
очереди буферов позволяют процессу-отправителю продолжать работу, не обращая внимания на получателя.
Основным недостатком буферизации сообщений является появление еще одного ресурса, которым нужно управлять. Этим ресурсом являются сами почтовые ящики.
К другому недостатку можно отнести статический характер этого ресурса: количество буферов для передачи сообщений через почтовый ящик фиксировано. Поэтому естественным стало появление механизмов, подобных почтовым ящикам, но реализованных на принципах динамического выделения памяти под передаваемые сообщения.
В операционных системах компании Microsoft тоже имеются почтовые ящики (mailslots). В частности, они достаточно часто используются при создании распределенных приложений для сети. При работе с ними в приложении, которое должно отправить сообщение другому приложению, необходимо указывать класс доставки сообщений. Различают два класса доставки. Первый класс (first-class delivery) гарантирует доставку сообщений; он ориентирован на сеансовое взаимодействие между процессами и позволяет организовать посылки типа «один к одному» и «один ко многим». Второй класс (second-class delivery) основан на механизме датаграмм, и он уже не гарантирует доставку сообщений получателю.
5.3 Конвейеры и очереди сообщений
Конвейеры
Программный канал связи (pipe), или, как его иногда называют, конвейер, транспортер, является средством, с помощью которого можно обмениваться данными между процессами. Принцип работы конвейера основан на механизме ввода-вывода файлов, то есть задача, передающая информацию, действует так, как будто она записывает данные в файл, в то время как задача, для которой предназначается эта информация, читает ее из этого файла. Операции записи и чтения осуществляются не записями, как это делается в обычных файлах, а потоком байтов. Таким образом, функции, с помощью которых выполняется запись в канал и чтение из него, являются теми же самыми, что и при работе с файлами. По сути, канал представляет собой поток данных между двумя (или более) процессами. Это упрощает программирование и избавляет программистов от использования каких-то новых механизмов. На самом деле конвейеры не являются файлами на диске, а представляют собой буферную память, работающую по принципу FIFO, то есть по принципу обычной очереди. Однако не следует путать конвейеры с очередями сообщений; последние реализуются иначе и имеют другие возможности.
Конвейер имеет определенный размер4, который не может превышать 64 Кбайт и работает циклически. Вспомните реализацию очереди на массивах, когда имеются указатели начала и конца очереди, которые перемещаются циклически по массиву. То есть имеется некий массив и два указателя: один показывает на первый элемент (указатель на начало — head), а второй — на последний (указатель на конец — tail). В начальный момент оба указателя равны нулю. Добавление самого первого элемента в пустую очередь приводит к тому, что указатели на начало и на конец принимают значение, равное 1 (в массиве появляется первый элемент). В последующем добавление нового элемента вызывает изменение значения второго указателя, поскольку он отмечает расположение именно последнего элемента очереди. Чтение (и удаление) элемента (читается и удаляется всегда первый элемент из созданной очереди) приводит к необходимости модифицировать значение указателя на ее начало. В результате операций записи (добавления) и чтения (удаления) элементов в массиве, моделирующем очередь элементов, указатели будут перемещаться от начала массива к его концу. При достижении указателем значения индекса последнего элемента массива значение указателя вновь становится единичным (если при этом не произошло переполнение массива, то есть количество элементов в очереди не стало большим числа элементов в массиве). Можно сказать, что мы как бы замыкаем массив в кольцо, организуя круговое перемещение указателей на начало и на конец, которые отслеживают первый и последний элементы в очереди. Сказанное иллюстрирует рис. 5.4. Именно так функционирует конвейер.
Как информационная структура конвейер описывается идентификатором, размером и двумя указателями. Конвейеры представляют собой системный ресурс. Чтобы начать работу с конвейером, процесс сначала должен заказать его у операционной системы и получить в свое распоряжение. Процессы, знающие идентификатор конвейера, могут через него обмениваться данными.
Указатель на конец Указатель на начало
Рис.5.4-Организация очереди в массиве
В качестве иллюстрации приведем основные системные запросы для работы с конвейерами, которые имеются в API OS/2.
Функция создания конвейера:
DosCreatePipe (SReadHandle, &WriteHandle, PipeSize):
Здесь ReadHandle — дескриптор чтения из конвейера,
WriteHandle — дескриптор записи в конвейер,
PipeSize — размер конвейера.
Функция чтения из конвейера:
DosRead (SReadHandle, (PVOID)SInform. sizeof(Inform), SBytesRead):
Здесь ReadHandle — дескриптор чтения из конвейера,
Inform — переменная любого типа,
sizeof(Inform) — размер переменной Inform,
BytesRead — количество прочитанных байтов.
Данная функция при обращении к пустому конвейеру будет ожидать, пока в нем не появится информация для чтения.
Функция записи в конвейер:
DosWrite (SWriteHandle, (PVOID)&Inform, sizeof(Inform), &BytesWrite);
Здесь WriteHandle — дескриптор записи в конвейер,
BytesWrite — количество записанных байтов.
Читать из конвейера может только тот процесс, который знает идентификатор соответствующего конвейера. При работе с конвейером данные непосредственно помещаются в него. Еще раз отметим, что из-за ограничения на размер конвейера программисты сталкиваются и с ограничениями на размеры передаваемых через него сообщений.
Очереди сообщений
Очереди (queues) сообщений предлагают более удобный метод связи между взаимодействующими процессами по сравнению с каналами, но в своей реализации они сложнее. С помощью очередей также можно из одной или нескольких задач независимым образом посылать сообщения некоторой задаче-приемнику. При этом только процесс-приемник может читать и удалять сообщения из очереди, а процессы-клиенты имеют право лишь помещать в очередь свои сообщения. Таким образом, очередь работает только в одном направлении. Если же необходима двухсторонняя связь, то можно создать две очереди.
Работа с очередями сообщений отличается от работы с конвейерами.
Во-первых, очереди сообщений предоставляют возможность использовать несколько дисциплин обработки сообщений:
FIFO — сообщение, записанное первым, будет первым и прочитано;
LIFO — сообщение, записанное последним, будет прочитано первым;
приоритетный доступ — сообщения читаются с учетом их приоритетов;
произвольный доступ — сообщения читаются в произвольном порядке. Тогда как канал обеспечивает только дисциплину FIFO.
Во-вторых, если при чтении сообщения оно удаляется из конвейера, то при чтении сообщения из очереди этого не происходит, и сообщение при желании может быть прочитано несколько раз.
В-третьих, в очередях присутствуют не непосредственно сами сообщения, а только их адреса в памяти и размер. Эта информация размещается системой в сегменте памяти, доступном для всех задач, общающихся с помощью данной очереди.
Каждый процесс, использующий очередь, должен предварительно получить разрешение на доступ в общий сегмент памяти с помощью системных запросов API, ибо очередь — это системный механизм, и для работы с ним требуются системные ресурсы и, соответственно, обращение к самой ОС. Во время чтения из очереди задача-приемник пользуется следующей информацией:
идентификатор процесса (Process Identifier, PID), который передал сообщение;
адрес и длина переданного сообщения;
признак необходимости ждать, если очередь пуста;
приоритет переданного сообщения;
номер освобождаемого семафора, когда сообщение передается в очередь.
Наконец, приведем перечень основных функций, управляющих работой очереди (без подробного описания передаваемых параметров, поскольку в различных ОС обращения к этим функциям могут существенно различаться):
|
CreateQueue |
- создание новой очереди; |
|
OpenQueue |
- открытие существующей очереди; |
|
ReadQueue |
- чтение и удаление сообщения из очереди; |
|
PeekQueue |
- чтение сообщения без его последующего удаления из очереди; |
|
WriteQueue |
- добавление сообщения в очередь; |
|
CloseQueue |
- завершение использования очереди; |
|
QueryQueue |
- определение числа элементов в очереди |
|
PurgeQueue |
- удаление из очереди всех сообщений; |
Контрольные вопросы и задачи
Какие последовательные вычислительные процессы мы называем параллельными и почему? Какие параллельные процессы называются независимыми, а какие — взаимодействующими?
Изложите алгоритм Деккера, позволяющий разрешить проблему взаимного исключения путем использования одной только блокировки памяти.
Объясните, как действует команда проверки и установки. Расскажите о работе команд BTS и BTR, которые имеются в процессорах с архитектурой ia32.
Расскажите о семафорах Дейкстры. Чем обеспечивается взаимное исключение при выполнении примитивов Р и V?
Изложите, как могут быть реализованы семафорные примитивы для мультипроцессорной системы?
Что такое мьютекс?
Изложите алгоритм решения задачи «поставщик-потребитель» при использовании семафоров Дейкстры.
Изложите алгоритм решения задачи «читатели-писатели» при использовании семафоров Дейкстры.
Что такое «монитор Хоара»? Приведите пример такого монитора.
Что представляют собой почтовые ящики?
Что представляют собой конвейеры (программные каналы)?
Что представляют собой очереди сообщений? Чем отличаются очереди сообщений от почтовых ящиков?
Лекция 11
Тема 6: Планирование и диспетчеризация процессов и задач
План лекции: 1. Операции планирования и диспетчеризации
Типы планирования процессора
Алгоритмы планирования
Литература:
А.В.Гордеев Операционные системы : учебник. 2007. 416с. Стр.50 – 71
М.Ф.Бондаренко, О.Г.Качко Операційні системи : навч.посібник. 2008. Стр.126-159
6.1 ОПЕРАЦИИ ПЛАНИРОВАНИЯ И ДИСПЕТЧЕРИЗАЦИИ
Самым критичным ресурсом в ЭВМ есть центральный процессор. Наличие нескольких процессоров в многопроцессорных системах только усложняет алгоритм управления временем процессоров. Для управления временем процессоров используются модули планирования и диспетчеризации.
Планирование –это формирование очереди процессов, готовых к выполнению.
Диспетчеризация –это выбор процессора для конкретного процесса, готового к выполнению.
Обычно процедуры обслуживания очереди процессов и выбора процессора выполняются одним модулем, который носит название планировщик – диспетчер. В очереди готовых процессов могут стоять процессы разных типов:
Отложенные процессы – это те процессы, которые были прерваны в связи с необходимостью проведения операции ввода – вывода или доступа к другим системным ресурсам;
Новые процессы – это процессы, только допущенные к выполнению;
Процессы, для которых завершилось отпущенное время.
В многозадачных системах в основной памяти одновременно содержится код нескольких процессов. В работе каждого процесса периоды использования процессора чередуются с ожиданием завершения выполнения операций ввода-вывода или некоторых внешних событий. Процессор (или процессоры) занят выполнением одного процесса, в то время как остальные находятся в состоянии ожидания.
Ключом к многозадачности является планирование. Обычно используются четыре типа планирования (табл. 6.1). Одно из них — планирование ввода-вывода. Планирование остальных трех типов, является планированием процессора.
Таблица 6.1-Типы планирования
Долгосрочное планирование |
Решение о добавлении процесса в пул выполняемых процессов |
Среднесрочное планирование |
Решение о добавлении процесса к числу процессов, полностью или частично размещенных в основной памяти |
Краткосрочное планирование |
Решение о том, какой из доступных процессов будет выполняться процессором |
Планирование ввода-вывода |
Решение о том, какой из запросов процессов на операции ввода- вывода будет обработан свободным устройством ввода-вывода |
Поскольку изучение планирования при использовании нескольких процессоров сопряжено с дополнительными сложностями, методологически правильнее сначала рассмотреть работу одного процессора, чтобы отчетливее увидеть отличия разных алгоритмов планирования.
6.2 ТИПЫ ПЛАНИРОВАНИЯ ПРОЦЕССОРА
Цель планирования процессора состоит в распределении во времени процессов, выполняемых процессором (или процессорами) таким образом, чтобы удовлетворять требованиям системы, таким, как время отклика, пропускная способность и эффективность работы процессора. Во многих системах планирование разбивается на три отдельные функции — долгосрочного, среднесрочного и краткосрочного планирования. Их названия соответствуют временным масштабам выполнения этих функций.
Долгосрочное планирование осуществляется при создании нового процесса и представляет собой решение о добавлении нового процесса к множеству активных в настоящий момент процессов.
Среднесрочное планирование является частью свопинга и представляет собой решение о добавлении процесса к множеству по крайней мере частично расположенных в основной памяти (и, следовательно, доступных для выполнения) процессов.
Краткосрочное планирование является решением о том, какой из готовых к выполнению процессов будет выполняться следующим.
На рис. 6.1 диаграмма переходов реорганизована таким образом, чтобы показать вложенность функций планирования.
Планирование оказывает большое влияние на производительность системы, поскольку именно оно определяет, какой процесс будет выполняться, а какой — ожидать выполнения.
На рис. 6.2 показаны очереди, включенные в диаграмму переходов состояний процесса.5
По сути, планирование представляет собой управление очередями с целью минимизации задержек и оптимизации производительности системы.
Долгосрочное планирование
Долгосрочное планирование указывает, какие программы допускаются к выполнению системой, и тем самым определяет степень многозадачности. Будучи допущенным к выполнению, задание (или пользовательская программа) становится процессом, который добавляется в очередь для краткосрочного планирования. В некоторых системах вновь созданный процесс добавляется к очереди среднесрочного планировщика, будучи целиком сброшенным на диск.
В пакетных системах (или в пакетной части операционной системы общего назначения) новое задание направляется на диск и хранится в очереди пакетных заданий, а долгосрочный планировщик по возможности создает процессы для заданий из очереди. В такой ситуации планировщик должен принять решение, во-первых, о том, способна ли операционная система работать с дополнительными процессами, а во-вторых, о том, какое именно задание (или задания) следует превратить в процесс (процессы). Рассмотрим вкратце эти решения.
Рис.6.1-Уровни планирования
Долгосрочное Тайм-аут
Рис. 6.2- Диаграмма планирования с участием очередей
Решение о том, когда следует создавать новый процесс, в общем определяется желаемым уровнем многозадачности. Чем больше процессов будет создано, тем меньший процент времени будет тратиться на выполнение каждого из них (поскольку в борьбе за одно и то же время конкурирует большее количество процессов). Таким образом, долгосрочный планировщик может ограничить степень многозадачности, с тем чтобы обеспечить удовлетворительный уровень обслуживания текущего множества процессов. Каждый раз при завершении задания планировщик решает, следует ли добавить в систему один или несколько новых процессов. Кроме того, долгосрочный планировщик может быть вызван в случае, когда относительное время простоя процессора превышает некоторый предопределенный порог.
Решение о том, какое из заданий должно быть добавлено в систему, может основываться на простейшем принципе «первым поступил — первым обслужен»; кроме того, для управления производительностью системы может использоваться и специальный инструментарий. Используемые в последнем случае критерии могут включать приоритет заданий, ожидаемое время выполнения и требования для работы устройств ввода-вывода. Например, если заранее доступна детально информация о процессах, планировщик может пытаться поддерживать в системе смесь из процессов, ориентированных на вычисления и загружающих процессор, и процессов с высокой интерактивностью ввода-вывода и малой загрузкой прс- цессора. Принимаемое решение может также зависеть от того, какие именно ресурсы ввода-вывода будут запрашиваться процессом.
В случае использования интерактивных программ в системах с разделением времени запрос на запуск процесса может генерироваться действиями пользователя по подключению к системе. Пользователи не просто вносятся в очередь в ожидании, когда система обработает их запрос на подключение. Вместо этого операционная система принимает всех зарегистрированных пользователей до насыщения системы (пороговое значение которого определяется заранее). После достижения состояния насыщения на все запросы на вход в систему будет получено сообщение о заполненности системы и временном прекращении доступа к ней с предложением повторить операцию входа попозже.
Среднесрочное планирование
Среднесрочное планирование является частью системы свопинга. Обычно решение о загрузке процесса в память принимается в зависимости от степени многозадачности; кроме того, в системе с отсутствием виртуальной памяти среднесрочное планирование также тесно связано с вопросами управления памятью. Таким образом, решение о загрузке процесса в память должно учитывать требования к памяти выгружаемого процесса.
Краткосрочное планирование
Рассматривая частоту работы планировщика, можно сказать, что долгосрочное планирование выполняется сравнительно редко, среднесрочное — несколько чаще. Краткосрочный же планировщик, известный также как диспетчер (dispatcher), работает чаще всего, определяя, какой именно процесс будет выполняться следующим.
Краткосрочный планировщик вызывается при наступлении события, которое может приостановить текущий процесс или предоставить возможность прекратить выполнение данного процесса в пользу другого. Вот некоторые примеры таких событий:
прерывание таймера;
прерывания ввода-вывода;
вызовы операционной системы;
сигналы.
6.3 Алгоритмы планирования
Критерии краткосрочного планирования
Основная цель краткосрочного планирования состоит в распределении процессорного времени таким образом, чтобы оптимизировать один или несколько аспектов поведения системы. Вообще говоря, имеется множество критериев оценки различных стратегий планирования.
Наиболее распространенные критерии могут быть классифицированы в двух плоскостях. Во-первых, мы можем разделить их на пользовательские и системные.
Пользовательские критерии связаны с поведением системы по отношению к отдельному пользователю или процессу. В качестве примера можно привести время отклика в интерактивной системе. Время отклика представляет собой интервал между передачей запроса и началом ответа на него. Его пользователь ощущает непосредственно, и, само собой, продолжительность интервала очень интересует его. Мы намерены создать стратегию планирования, обеспечивающую качественный сервис для пользователей? В таком случае для времени отклика следует установить порог, например в 2 секунды. Тогда цель механизма планирования должна заключаться в максимизации количества пользователей, среднее время отклика для которых не превышает 2 секунд.
Системные критерии ориентированы на эффективность и полноту использования процессора. В качестве примера можно привести пропускную способность, которая представляет собой скорость завершения процессов. Это, безусловно, эффективная мера производительности системы, которая должна быть максимизирована. Однако она в большей степени ориентирована на производительность системы, а не на обслуживание пользователя, так что и удовлетворять она будет системного администратора, а не пользователей системы.
В то время как пользовательские критерии важны почти для всех систем, системные критерии для однопользовательских систем не так значимы. В этом случае, пожалуй, достижение высокой эффективности использования процессора или высокая производительность не так существенны, как скорость ответа системы приложению пользователя.
Еще один способ разделения критериев — на те, которые связаны с производительностью, и те, которые с производительностью непосредственно не связаны.
Ориентированные на производительность критерии выражаются числовыми значениями и обычно достаточно легко измеримы — примерами их могут служить время отклика и пропускная способность.
Критерии, не связанные с производительностью непосредственно, либо качественны по своей природе, либо трудно поддаются измерениям и анализу. Примером такого критерия служит предсказуемость. Желательно, чтобы предоставляемые пользователю сервисы в разное время имели одни и те же характеристики, не зависящие от других задач, выполняемых в настоящее время системой. До некоторой степени этот критерий является измеримым — путем вычисления отклонений как функции от загрузки системы. Однако провести такие измерения оказывается вовсе не просто.
Таблица 6.2- Критерии планирования
Пользовательские, связанные с производительностью |
|
Время оборота |
Интервал времени между подачей процесса и его завершением Включает время выполнения, а также время, затраченное на ожидание ресурсов, в том числе и процессора. Критерий вполне применим для пакетных заданий |
Время отклика |
В интерактивных процессах это время, истекшее между подачей запроса и началом получения ответа на него. Зачастую процесс может начать вывод информации пользователю, еще не окончил полной обработки запроса, так что описанный критерий — наиболее подходящий с точки зрения пользователя. Стратегия планирования должна пытаться сократить время получения ответа при максимизации количества интерактивных пользователей, время отклика для которых не выходит за заданные пределы |
Предельный срок |
При указании предельного срока завершения процесса планирование должно подчинить ему все прочие цели максимизации количества процессов, завершающихся в срок |
Пользовательские, иные |
|
Предсказуемость |
Данное задание должно выполняться примерно за одно и то же количество времени и с одной и той же стоимостью, независимо от загрузи;: системы. Большие вариации времени исполнения или времени отклике дезориентируют пользователей. Это явление может сигнализировать о больших колебаниях загрузки или о необходимости дополнительной настройки системы для устранения нестабильности ее работы |
Системные, связанные с производительностью |
|
Пропускная способность |
Стратегия планирования должна пытаться максимизировать количество процессов, завершающихся за единицу времени, что является мерой количества выполненной системой работы. Очевидно, что эта величина зависит от средней продолжительности процесса; однако на нее влияет и используемая стратегия планирования |
Использование процессора |
Этот показатель представляет собой процент времени, в течение которого процессор оказывается занят. Для дорогих совместно используемых систем этот критерий достаточно важен; в однопользовательских же и некоторых других системах (типа систем реального времени) этот критерий менее важен по сравнению с рядом других |
Системные, иные |
|
Беспристрастность |
При отсутствии дополнительных указаний от пользователя или системы все процессы должны рассматриваться как равнозначные и ни один процесс не должен подвергнуться голоданию |
Использование приоритетов |
Если процессам назначены приоритеты, стратегия планирования должна отдавать предпочтение процессам с более высоким приоритетом |
Баланс ресурсов |
Стратегия планирования должна поддерживать занятость системных ресурсов. |
В табл. 6.2 приведены ключевые критерии планирования. Все они взаимозависимы, и достичь оптимального результата по каждому из них одновременно невозможно. Например, обеспечение удовлетворительного отклика может потребовать применения алгоритма с высокой частотой переключения процессов, что повысит накладные расходы и, соответственно, снизит пропускную способность системы. Следовательно, разработка стратегии планирования представляет собой поиск компромисса среди противоречивых требований; относительный вес каждого из критериев определяется природой и предназначением разрабатываемой системы.
В большинстве интерактивных операционных систем с одним пользователем или с разделяемым временем критичным требованием является время отклика.
Лекция 12
План лекции:
Планирование и диспетчеризация процессов и задач
Дисциплины диспетчеризации
Литература:
А.В.Гордеев Операционные системы : учебник. 2007. 416с. Стр.50 - 71
6.4 Планирование и диспетчеризация процессов и задач
Когда говорят о диспетчеризации, то всегда в явном или неявном виде подразумевают понятие задачи (потока выполнения). Очевидно, что на распределение ресурсов влияют конкретные потребности тех задач, которые должны выполняться параллельно. Другими словами, можно столкнуться с ситуациями, когда невозможно эффективно распределять ресурсы с тем, чтобы они не простаивали. Например, пусть всем выполняющимся процессам требуется некоторое устройство с последовательным доступом. Но поскольку, как мы уже знаем, оно не может разделяться между параллельно выполняющимися процессами, то процессы вынуждены будут очень долго ждать своей очереди, то есть недоступность одного ресурса может привести к тому, что длительное время не будут использоваться многие другие ресурсы.
Если же мы возьмем такой набор процессов, что они не будут конкурировать между собой за неразделяемые ресурсы при своем параллельном выполнении, то, скорее всего, процессы смогут выполниться быстрее (из-за отсутствия дополнительных ожиданий), да и имеющиеся в системе ресурсы, скорее всего, будут использоваться более эффективно.
Таким образом, возникает задача подбора такого множества процессов, которые при своем выполнении будут как можно реже конфликтовать за имеющиеся в системе ресурсы. Такая задача называется планированием вычислительных процессов.
Задача планирования процессов возникла очень давно — в первых пакетных операционных системах при планировании пакетов задач, которые должны были выполняться на компьютере и по возможности бесконфликтно и оптимально использовать его ресурсы. На первый план уже очень давно вышли задачи динамического (или краткосрочного) планирования, то есть текущего наиболее эффективного распределения ресурсов, возникающего практически по каждому событию. Задачи динамического планирования стали называть диспетчеризацией.
Очевидно, что планирование процессов осуществляется гораздо реже, чем текущее распределение ресурсов между уже выполняющимися задачами. Основное различие между долгосрочным и краткосрочным планировщиками заключается в частоте их запуска, например: краткосрочный планировщик может запускаться каждые 30 или 100 мс, долгосрочный — один раз в несколько минут (или чаще; тут многое зависит от общей длительности решения заданий пользователей).
Долгосрочный планировщик решает, какой из процессов, находящихся во входной очереди, в случае освобождения ресурсов памяти должен быть переведен в очередь процессов, готовых к выполнению. Долгосрочный планировщик выбирает процесс из входной очереди с целью создания неоднородной мультипрограммной смеси. Это означает, что в очереди готовых к выполнению процессов должны находиться в разной пропорции как процессы, ориентированные на ввод-вывод, так и процессы, ориентированные преимущественно на активное использование центрального процессора.
Краткосрочный планировщик решает, какая из задач, находящихся в очереди готовых к выполнению, должна быть передана на исполнение.
В большинстве современных операционных систем, с которыми мы сталкиваемся, долгосрочный планировщик отсутствует.
6.3.1 Планирование вычислительных процессов и стратегии планирования
Прежде всего, следует отметить, что при рассмотрении стратегий планирования, как правило, идет речь о краткосрочном планировании, то есть о диспетчеризации.
Долгосрочное планирование, как мы уже отметили, заключается в подборе таких вычислительных процессов, которые бы меньше всего конкурировали между собой за ресурсы вычислительной системы. Иногда используется термин стратегия обслуживания.
Стратегия планирования определяет, какие процессы мы планируем на выполнение для того, чтобы достичь поставленной цели. Известно большое количество различных стратегий выбора процесса, которому необходимо предоставить процессор. Среди них, прежде всего, можно выбрать следующие:
по возможности заканчивать вычисления (вычислительные процессы) в том же самом порядке, в котором они были начаты;
отдавать предпочтение более коротким вычислительным задачам;
предоставлять всем пользователям (процессам пользователей) одинаковые услуги, в том числе и одинаковое время ожидания.
Когда говорят о стратегии обслуживания, всегда имеют в виду понятие процесса, а не понятие задачи, поскольку процесс, как мы уже знаем, может состоять из нескольких потоков выполнения (т.е. задач).
На сегодняшний день абсолютное большинство компьютеров — это персональные IBM-совместимые компьютеры, работающие на платформах Windows компании Microsoft. Это однопользовательские диалоговые мультипрограммные и мультизадачные системы. При создании операционных систем для персональных компьютеров разработчики, прежде всего, стараются обеспечить комфортную работу с системой, то есть основные усилия уходят на проработку пользовательского интерфейса. Что касается эффективности организации вычислений, то она, видимо, тоже должна оцениваться с этих позиций. Если же считать системы Windows операционными системами общего назначения, что тоже возможно, ибо эти системы повсеместно используют для решения самых разнообразных задач автоматизации, то также следует признать, что принятые в системах Windows стратегии обслуживания приводят к достаточно высокой эффективности вычислений. Некоторым даже удается использовать системы Windows NT/2000 для решения задач реального времени. Однако выбор этих операционных систем для таких задач скорее всего делается либо вследствие некомпетентности, либо из-за невысоких требований ко времени отклика и гарантиям обслуживания со стороны самих систем реального времени, которые реализуются на Windows NT/2000.
Прежде всего, система, ориентированная на однопользовательский режим, должна обеспечить хорошую реакцию системы на запросы от того приложения, с которым сейчас пользователь работает. Мало пользователей, которые могут параллельно работать с большим числом приложений. Поэтому по умолчанию для задачи, с которой пользователь непосредственно работает и которую называют задачей переднего плана (foreground task), система устанавливает более высокий уровень приоритета. В результате процессорное время прежде всего предоставляется текущей задаче пользователя, и он не будет испытывать лишний раз дискомфорт из-за медленной реакции системы на его запросы. Для обеспечения надлежащей работы коммуникационных процессов и для возможности выполнять системные функции приоритет задач пользователя должен быть ниже, чем у тех задач, которые реализуют операции ввода-вывода и иные управляющие функции.
Например, в Windows 2000 можно открыть окно Свойства системы, перейти на вкладку Дополнительно, щелчком на кнопке Параметры быстродействия открыть одноименное окно и с помощью переключателя в разделе Отклик приложений установить режим Оптимизировать быстродействие приложений. Это будет соответствовать выбору такой стратегии диспетчеризации задач, в соответствии с которой приоритет на получение процессорного времени будут иметь задачи пользователя, а не фоновые служебные вычисления.
Например, если нужно обработать несколько десятков музыкальных или графических файлов, причем каждый файл имеет большие размеры, то выполнение всей этой работы как множества параллельно исполняющихся задач будет завершено за меньшее время, если указать стратегию равенства обслуживания. Должно быть очевидным, что любой другой вариант решения этой задачи потребует больше времени.
Например, последовательное выполнение задач обработки каждого файла (то есть обработка следующего файла может начинаться только по окончании обработки предыдущего) приведет к самому длительному варианту.
Стратегия предоставления процессорного времени в первую очередь текущей задаче пользователя, которая установлена в системах Windows по умолчанию, приведет нас к промежуточному (по затратам времени) результату.
Очевидно, что в идеале в очереди готовых к выполнению задач должны находиться в разной пропорции как задачи, ориентированные на ввод-вывод, так и задачи, ориентированные преимущественно на работу с центральным процессором. Практически все операционные системы стараются учесть это требование, однако не всегда оно выполняется настолько удачно, что пользователь получает превосходное время реакции системы на свои запросы и при этом видит, что его ресурсоемкие приложения выполняются достаточно быстро.
6.4 Дисциплины диспетчеризации
Дисциплина диспетчеризации - это правила формирования очереди готовых к выполнению задач, в соответствии с которыми формируется эта очередь (список).
Известно большое количество дисциплин диспетчеризации. Иногда их называют дисциплинами обслуживания, опуская тот факт, что речь идет о распределении процессорного времени. Одни дисциплины диспетчеризации дают наилучшие результаты для одной стратегии обслуживания, в то время как для другой стратегии они могут быть вовсе неприемлемыми.
Различают два больших класса дисциплин обслуживания: бес приоритетные и приоритетные.
При бес приоритетном обслуживании выбор задач производится в некотором заранее установленном порядке без учета их относительной важности и времени обслуживания.
При приоритетном обслуживании отдельным задачам предоставляется преимущественное право попасть в состояние исполнения.
Перечень дисциплин обслуживания и их классификация приведены на рис. 6.1.
Рисунок 6.1- Перечень дисциплин обслуживания и их классификация
В концепции приоритетов имеем следующие варианты:
- приоритет, присвоенный задаче, является величиной постоянной;
- приоритет изменяется в течении времени решения задачи (динамический приоритет).
Диспетчеризация с динамическими приоритетами требует дополнительных расходов на вычисление значений приоритетов исполняющихся задач, поэтому во многих операционных системах реального времени используются методы диспетчеризации на основе абсолютных приоритетов. Это позволяет сократить время реакции системы на очередное событие, однако требует детального анализа всей системы для правильного присвоения соответствующих приоритетов всем исполняющимся задачам с тем, чтобы гарантировать обслуживание.
Рассмотрим некоторые основные (наиболее часто используемые) дисциплины диспетчеризации.
Дисциплина FCFS
Самой простой в реализации является дисциплина FCFS (First Come First Served — первым пришел, первым обслужен), согласно которой задачи обслуживаются «в порядке очереди», то есть в порядке их появления.
Те задачи, которые были заблокированы в процессе работы (попали в какое-либо из состояний ожидания, например из-за операций ввода-вывода), после перехода в состояние готовности вновь ставятся в эту очередь готовности.
Достоинства:
-не требует внешнего вмешательства в ход вычислений, при ней не происходит перераспределения процессорного времени.
-простота реализации
-малые расходы системных ресурсов на формирование очереди задач.
Недостатки:
-при увеличении загрузки вычислительной системы растет и среднее время ожидания обслуживания, причем короткие задания (требующие небольших затрат машинного времени) вынуждены ожидать столько же, сколько трудоемкие задания.
Про нее можно сказать, что она относится к не вытесняющим дисциплинам.
Дисциплина обслуживания SJN
Дисциплина обслуживания SJN (Shortest Job Next — следующим выполняется самое короткое задание) требует, чтобы для каждого задания была известна оценка в потребностях машинного времени.
Необходимость сообщать операционной системе характеристики задач с описанием потребностей в ресурсах вычислительной системы привела к тому, что были разработаны соответствующие языковые средства. В частности, ныне уже забытый язык JCL (Job Control Language — язык управления заданиями) был одним из наиболее известных.
Пользователи вынуждены были указывать предполагаемое время выполнения задачи и для того, чтобы они не злоупотребляли возможностью указать заведомо меньшее время выполнения (с целью возможности получить результаты раньше других), ввели подсчет реальных потребностей. Диспетчер задач сравнивал заказанное время и время выполнения и в случае превышения указанной оценки потребности в данном ресурсе ставил данное задание не в начало, а в конец очереди. Еще в некоторых операционных системах в таких случаях использовалась система штрафов, при которой в случае превышения заказанного машинного времени оплата вычислительных ресурсов осуществлялась уже по другим расценкам.
Особенности:
-предполагается, что имеется только одна очередь заданий, готовых к выполнению.
-задания, которые в процессе своего исполнения были временно заблокированы (например, ожидали завершения операций ввода- вывода), вновь попадают в конец очереди готовых к выполнению наравне с вновь поступающими.
Это приводило к тому, что задания, которым требовалось очень немного времени для своего завершения, вынуждены были ожидать процессор наравне с длительными работами, что не всегда хорошо.
Дисциплина SRT
Для устранения этого недостатка и была предложена дисциплина SRT (Shortest Remaining Time) — следующим будет выполняться задание, которому осталось меньше всего выполняться на процессоре.
Все эти три дисциплины обслуживания могут использоваться для пакетных режимов обработки, когда пользователю не нужно ждать реакции системы — он просто сдает свое задание и через несколько часов получает результаты вычислений..
Если же это однопользовательская система, но с возможностью мультипрограммной обработки, то желательно, чтобы те программы, с которыми непосредственно работает пользователь, имели лучшее время реакции, нежели фоновые задания. При этом желательно, чтобы некоторые приложения, выполняясь без непосредственного участия пользователя (например, программа получения электронной почты, использующая модем и коммутируемые линии для передачи данных), тем не менее, гарантированно получали необходимую им долю процессорного времени.
Для решения перечисленных проблем используется дисциплина обслуживания, называемая карусельной (Round Robin, RR), и приоритетные методы обслуживания.
Дисциплина обслуживания RR
Дисциплина обслуживания RR предполагает, что каждая задача получает процессорное время порциями или, как говорят, квантами времени (time slice) q.
После окончания кванта времени q задача снимается с процессора, и он передается следующей задаче. Снятая задача ставится в конец очереди задач, готовых к выполнению.
В некоторых операционных системах есть возможность указывать в явном виде величину кванта времени или диапазон возможных значений, тогда система будет стараться выбирать оптимальное значение сама. Например, в операционной системе OS/2 в файле CONFIG.SYS есть возможность с помощью оператора TIMESLICE указать минимальное и максимальное значения для кванта q. Так, например, строка TIM ESLICE=32,256 указывает, что минимальное значение равно 32 мс, а максимальное — 256. Если некоторая задача прервана, поскольку израсходован выделенный ей квант времени q, то следующий выделенный ей интервал будет увеличен на время, равное одному периоду таймера (около 32 мс), и так до тех пор, пока квант времени не станет равным максимальному значению, указанному в операторе TIMESLICE. Этот метод позволяет OS/2 уменьшить накладные расходы на переключение задач в том случае, если несколько задач параллельно выполняют длительные вычисления. Следует заметить, что диспетчеризация задач в этой операционной системе реализована, пожалуй, наилучшим образом с точки зрения реакции системы и эффективности использования процессорного времени.
Дисциплина карусельной диспетчеризации более всего подходит для случая, когда все задачи имеют одинаковые права на использование ресурсов центрального процессора. Однако как мы знаем, равенства в жизни гораздо меньше, чем неравенства. Одни задачи всегда нужно решать в первую очередь, тогда как остальные могут подождать. Это можно реализовать за счет того, что одной задаче мы (или диспетчер задач) присваиваем один приоритет, а другой задаче — другой.
Задачи в очереди будут располагаться в соответствии с их приоритетами.
Формирует очередь диспетчер задач. Процессор в первую очередь будет предоставляться задаче с самым высоким приоритетом, и только если ее потребности в процессоре удовлетворены или она попала в состояние ожидания некоторого события, диспетчер может предоставить его следующей задаче. Многие дисциплины диспетчеризации по-разному используют основную идею карусельной диспетчеризации и механизм приоритетов.
Дисциплина диспетчеризации RR — это одна из самых распространенных дисциплин.
В своей простейшей реализации дисциплина карусельной диспетчеризации предполагает, что все задачи имеют одинаковый приоритет. Если же необходимо ввести механизм приоритетного обслуживания, то это, как правило, делается за счет организации нескольких очередей. Процессорное время предоставляется в первую очередь тем задачам, которые стоят в самой привилегированной очереди.
Качество диспетчеризации и гарантии обслуживания
Одна из проблем, которая возникает при выборе подходящей дисциплины обслуживания — это гарантия обслуживания. Дело в том, что в некоторых дисциплинах, например в дисциплине абсолютных приоритетов, низкоприоритетные процессы получаются обделенными многими ресурсами и, прежде всего, процессорным временем. Возникает реальная дискриминация низкоприоритетных задач, в результате чего они достаточно длительное время могут не получать процессорное время. В конце концов, некоторые процессы и задачи вообще могут быть не выполнены к заданному сроку. Известны случаи, когда вследствие высокой загрузки вычислительной системы отдельные процессы вообще не выполнились, несмотря на то что прошло несколько лет (!) с момента их планирования. Поэтому вопрос гарантии обслуживания является очень актуальным.
Более жестким требованием к системе, чем просто гарантированное завершение процесса, является его гарантированное завершение к указанному моменту времени или за указанный интервал времени.
1 Ri — это просто имя переменной для процесса с номером і.
2 Совокупность однородных динамически распределяемых объектов, например блоков памяти одинаковой длины.
3 Р — от голландского Proberen (проверить), V — от голландского Verhogen (увеличить).
4 Механизм конвейеров, впервые введенный в UNIX-системах, имеет максимальный размер 64 Кбайт, поскольку в 16-разрядных мини-ЭВМ, для которых создавалась эта ОС, нельзя было иметь массив данных большего размера.
5 Для простоты восприятия на рис. 9.3 новые процессы показаны как непосредственно становящиеся в очередь готовых к выполнению, в то время как на рис. 9.1 и 9.2 видно, что новый процесс может быть как в состоянии готовности, так и приостановленным.