Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОС М2 2011.doc
Скачиваний:
7
Добавлен:
12.11.2019
Размер:
698.88 Кб
Скачать
  • Операционная система должна распределять и освобождать различные ре­сурсы для

    каждого активного процесса, в том числе следующие.

    • Процессорное время

    • Память: большинство ОС используют схему виртуаль­ной памяти.

    • Файлы.

    • Устройства ввода-вывода:

    3. Операционная система должна защищать данные и физические ресурсы ка­ждого процесса от непреднамеренного воздействия других процессов, что включает использование технологий, применяющихся для работы с памя­тью, файлами и устройствами ввода-вывода.

    4. Результат работы процесса не должен зависеть от скорости его выполнения по отношению

    к другим параллельно выполняющимся процессам.

    4.2 Параллелизм в системах аппаратного оборудования

    Параллелизм заложен уже на уровне разрядов. Так, операция сложения чисел реализована путем параллельного сложения разрядов с учетом переноса. Команды процессора выполняются параллельно за счет использования конвейера и суперскалярности. Суперскалярнисть означает наличие нескольких блоков для параллельного выполнения операций.

    К сожалению, параллельное выполнение команд возможно не всегда по следующим причинам:

    • последовательные команды могут быть зависимыми по результатам. Это означает, что результат выполнения последующей команды зависит от результата выполнения предыдущей команды;

    • команды перехода нарушают порядок выполнения команд, оттого результат выполнения следующей команды аннулируется;

    • современные процессоры используют специализированные блоки для целочисловых расчетов, для вычислений с плавающей точкой, для операций умножения и др.

    В связи с последним недостатком в современных процессорах используется технология HYPER THREADING. Содержание этой технологии заключается в том, что параллельные устройства процессора используются не для выполнения дежурных команд одного потока, а для различных потоков одного процесса или даже различных процессов. В этом случае ОС рассматривает один физический процессор как несколько логических процессоров - ОС их использует для различных потоков. В этом случае говорят о многоядерном процессоре. Пример такого процессора - процессор ITANIUM.

    Процессоры внешних устройств работают параллельно с ЦП, если одно устройство выполняет операцию ввода / вывода, а другое - вычислительные операции. Это обеспечивает параллельное выполнение нескольких операций даже на однопроцессорной системе.

    В многопроцессорной системе параллельно работают все процессоры.

    Определим способы осуществления многозадачности:

    1. Сама задача может время от времени передавать управление другой задаче.

    2. Управление может в порядке очереди отбираться у одной задачи и передаваться другой задаче.

    Первый способ получил название кооперативной (не вытесненной) многозадачности, а второй, используемый в большинстве современных ОС - вытесненной многозадачности.

    4.3 Параметры многозадачной вычислительной системы

    Эффективность работы многозадачной вычислительной системы определяется тремя параметрами:

    пропускной способностью (количеством выполненных программ за единицу времени);

    реактивностью (временами отзыва каждой запущенной на выполнение программы);

    динамичностью (способностью обеспечивать удобство работы пользователя в динамически переменчивой обстановке).

    К сожалению, эти параметры взаимно исключают один одного. Это привело к делению ОС на три типа, каждый из которых обеспечивает наилучшее значение для одного из этих параметров.

    Наибольшую пропускную способность с точки зрения одной программы имеют системы пакетной обработки. В этом случае не расходуется время на сохранение и возобновление текущего состояния задачи при ее вытеснении. Однако в этом случае процессор простаивает во время выполнения операций, в которых он не участвует. Определенную часть времени своего выполнения программа расходует на операции ввода/вывода (которые, как правило, не требуют участия центрального процессора, а следовательно, могут выполняться параллельно с программой). Пока одна с программ ожидает завершения операции ввода/вывода, процессор выполняет другую программу. В итоге многозадачность обеспечивает большую пропускную способность, чем характерное для систем пакетной обработки однозадачное выполнение программ в порядке очереди.

    Таким образом, наилучшими с точки зрения пропускной способности являются ОС с невытеснявшей многозадачностью.

    Второй параметр - реактивность - обеспечивает время отзыва (время выполнения) программы. То есть реактивная система (такие системы называются системами реального времени), гарантирует, что программа выполнится в определенный промежуток времени.

    Третий параметр - динамичность - определяет удобство работы пользователя, который желает иметь возможность работать одновременно с несколькими программами интерактивно, причем заблаговременно неизвестно, когда и с которыми. То есть алгоритмы распределения ресурсов компьютера в такой системе должны приемлемый вести себя с неизвестным предварительно количеством программ и запрошенным количеством ресурсов. Такие системы называются системами распределения времени, к ним принадлежат популярные WINDOWS, LINUX и др.

    На первый взгляд кажется, что требования динамичности и реактивности похожие, но это не так. В системах реального времени предварительно известно, которые программы будут запущены и которые ресурсы им понадобятся, что позволяет самое эффективное спланировать распределение ресурсов (следовательно, гарантировать, что в любой ситуации программа будет выполнена за определенный промежуток времени). В системах распределения времени никаких предположений относительно количества и порядка запуска добавлений сделать нельзя.

    4.4 Параллелизм в системах программного обеспечения

    Программы, которые выполняются параллельно, или устройства, которые работают параллельно, как правило не должны знать друг о друге и не мешать одна одной. К тому же, различные устройства могут работать с различной скоростью. Исходя из этого единичный результат выполнения работы должен быть независимым и такой единицей результата является процесс. Таким образом, один с признаков процессов - независимые результаты работы, которые выполняються с различной скоростью.

    Не все процессы должны быть независимыми. Возможны определенные требования взаимодействия между параллельно работающими процессами. Эти взаимодействия осуществляется по предварительно определенным правилам.

    Заметим, что параллелизм может быть обеспеченный не только на уровне отдельных процессов, но и внутри процесса за счет использования языковых возможностей. Существует целая теория параллельных вычислений и их использования для решения конкретных задач. Некоторые языки программирования обеспечивают задания участков кода, которые могут выполняться параллельно. В наше время, когда многопроцессорные системы приобрели широкое применение, эта проблема становится все актуальнее.

    Лекция 7

    План лекции:

    5. Аппаратная поддержка многозадачного режима

    1. Алгоритм аппаратного переключения между задачами

    2. Параллелизм в системах программного обеспечения

    Литература:

    М.Ф.Бондаренко, О.Г.Качко Операційні системи : навч.посібник. 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, что означает, что по завершении новой задачи необходимо вернуться к выполнению старой.

      1. Алгоритм аппаратного переключения между задачами

    Алгоритм содержит в себе такие пункты.

    1. Из операнда команды JMR или CALL процессор получает селектор, который указывает на TSS или шлюз TSS.

    2. Процессор проверяет наличие полномочий старой задачи для переключения задач.

    3. Процессор проверяет наличие в памяти TSS новой задачи и его размер (минимально допустимый — не меньше 103).

    4. Процессор проверяет доступность новой задачи (она не должна быть занятой -флажок BUSY сброшен).

    5. Если для переключения задач используется команда JMP, флажок BUSY для старой задачи сбрасывается. Если используется команда IRET, флажок BUSY переписывается в копии регистра EFLAG.

    6. Выбирается адрес TSS для текущей (старой) задачи из регистра задачи, и туда записываются все динамические поля, в том числе содержание регистра ЕIР, который определяет адрес дежурной команды в прерванной задаче.

    7. Если для переключения задач используется команда CALL, в образе регистра EFLAGS в стеке устанавливается флажок вложенности задач (NT). Если используется команда IRET, флажок NT в образе регистра EFLAGS в стеке сбрасывается.

    8. Для новой задачи, которая инициирована командами CALL, JMP, устанавливается флажок занятости BUSY в дескрипторе TSS этой задачи.

    9. Устанавливается флаг TS в образе регистра CR0 в TSS этой задачи. Бит TS полезный системным программам для координации работы целочислового блока и блока операций с плавающей точкой. Бит TS указывает на то, что содержание блока операций с плавающей точкой может отличаться от соответствующего содержания для текущей задачи.

    10. Загружается регистр задач TR, что теперь должен указывать на TSS новой задачи.

    11. Загружаются все регистры с TSS этой задачи, в том числе CR3, благодаря чему будет использован виртуальный адресный простор новой задачи, ЕIР, то есть следующей будет выполнена команда новой задачи.

    Если при выполнении какого-то пункта алгоритма произошла ошибка, алгоритм завершается.

    Многозадачный режим для многопроцессорной системы

    В наше время многопроцессорные системы получили значительное распространение. Требование относительно эффективной поддержки многопроцессорного режима является одним из важнейших для современных ОС.

    Рассмотрим аппаратную поддержку этого требования. Допустим, что все процессоры, включенные в систему, одинаковые. Такие многопроцессорные системы называются симметричными. Наряду с такими процессорами в системе используются специализированные процессоры (графические, видео, для обеспечения связи и др.). Все эти процессоры используют одну общую системную шину.

    Основные трудности, которые необходимо преодолеть в данном случае — это синхронизация работы процессоров и обеспечения высокопродуктивного доступа к памяти. В частности, задача синхронизации встает, если два (или больше) процессора одновременно пытается получить доступ к одной ячейки памяти. Задача высокопродуктивного доступа к памяти решается посредством кэша, но в этом случае один процессор может обращаться к данным, которые находятся в кэш-памяти другого процессора, в этом случае возникает проблема доступа к достоверным данным..

    Лекция 8

    Тема 5: Организация параллельных взаимодействующих вычислений

    План лекции:

    1. Независимые и взаимодействующие вычислительные процессы.

    2. Средства синхронизации и связи взаимодействующих вычислительных процессов

    Литература:

    А.В.Гордеев Операционные системы : учебник. 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). Решение проблемы заключается в организации такого доступа к критическому ресурсу, при котором только одному процессу разрешается входить в критичес­кую секцию. Данная задача только на первый взгляд кажется простой, ибо крити­ческая секция, вообще говоря, не является последовательностью операторов про­граммы, а является процессом, то есть последовательностью действий, которые выполняются этими операторами. Другими словами, несколько процессов могут выполнять критические секции, использующие одну и ту же последовательность операторов программы.

    Когда какой-либо процесс находится в своей критической секции, другие процес­сы могут, конечно, продолжать свое исполнение, но без входа в их критические секции. Взаимное исключение необходимо только в том случае, когда процессы обращаются к разделяемым (общим) данным. Если же они выполняют операции, которые не ведут к конфликтным ситуациям, процессы должны иметь возмож­ность работать параллельно. Когда процесс выходит из своей критической секции, то одному из остальных процессов, ожидающих входа в свои критические секции, должно быть разрешено продолжить работу (если в этот момент действительно есть процесс в состоянии ожидания входа в свою критическую секцию).

    Обеспечение взаимного исключения является одной из ключевых проблем параллельного программирования. При этом можно перечислить требования к крити­ческим секциям.

    1. В любой момент времени только один процесс должен находиться в своей кри­тической секции.

    2. Ни один процесс не должен бесконечно долго находиться в своей критической секции.

    3. Ни один процесс не должен бесконечно долго ожидать разрешение на вход в свою критическую секцию. В частности:

    • никакой процесс, бесконечно долго находящийся вне своей критической секции (что допустимо), не должен задерживать выполнение других про­цессов, ожидающих входа в свои критические секции (другими словами, процесс, работающий вне своей критической секции, не должен блокиро­вать критическую секцию другого процесса);

    • если два процесса хотят войти в свои критические секции, то принятие ре­шения о том, кто первым войдет в критическую секцию, не должно быть бесконечно долгим.

    Если процесс, находящийся в своей критической секции, завершается естествен­ным или аварийным путем, то режим взаимного исключения должен быть от­менен, с тем чтобы другие процессы получили возможность входить в свои кри­тические секции. Было предложено несколько способов решения этой проблемы: программных и аппаратных; локальных низкоуровневых и глобальных высокоуровневых; предус­матривающих свободное взаимодействие между процессами и требующих строго­го соблюдения протоколов.

    Лекция 9

    План лекции:

    1. Средства синхронизации и связи взаимодействующих вычислительных процессов.

      1. Блокировка памяти

      2. Синхронизация процессов с помощью операций проверки и установки

      3. Семафорные примитивы Дейкстры

    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

    План лекции:

    1. Почтовые ящики

    2. Конвейеры и очереди сообщений

    Литература:

    А.В.Гордеев Операционные системы : учебник. 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

    - удаление из очереди всех сообщений;

    Контрольные вопросы и задачи

    1. Какие последовательные вычислительные процессы мы называем параллель­ными и почему? Какие параллельные процессы называются независимыми, а какие — взаимодействующими?

    2. Изложите алгоритм Деккера, позволяющий разрешить проблему взаимного исключения путем использования одной только блокировки памяти.

    3. Объясните, как действует команда проверки и установки. Расскажите о рабо­те команд BTS и BTR, которые имеются в процессорах с архитектурой ia32.

    4. Расскажите о семафорах Дейкстры. Чем обеспечивается взаимное исключе­ние при выполнении примитивов Р и V?

    5. Изложите, как могут быть реализованы семафорные примитивы для мульти­процессорной системы?

    6. Что такое мьютекс?

    7. Изложите алгоритм решения задачи «поставщик-потребитель» при исполь­зовании семафоров Дейкстры.

    8. Изложите алгоритм решения задачи «читатели-писатели» при использова­нии семафоров Дейкстры.

    9. Что такое «монитор Хоара»? Приведите пример такого монитора.

    10. Что представляют собой почтовые ящики?

    11. Что представляют собой конвейеры (программные каналы)?

    12. Что представляют собой очереди сообщений? Чем отличаются очереди сооб­щений от почтовых ящиков?

    Лекция 11

    Тема 6: Планирование и диспетчеризация процессов и задач

    План лекции: 1. Операции планирования и диспетчеризации

    1. Типы планирования процессора

    2. Алгоритмы планирования

    Литература:

    А.В.Гордеев Операционные системы : учебник. 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

    План лекции:

    1. Планирование и диспетчеризация процессов и задач

    2. Дисциплины диспетчеризации

    Литература:

    А.В.Гордеев Операционные системы : учебник. 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 видно, что новый процесс может быть как в состоянии готовности, так и приостановленным.