Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
223
Добавлен:
02.05.2014
Размер:
2.83 Mб
Скачать

28. Режимы ядра в Unix

В действительности расположенный в ядре планировщик Unix работает не со "статическими" приоритетами nice, а с приоритетами, динамически изменяемыми по ходу выполнения процесса. Так, в BSD-системах к процессам, которые "скушали" определенный объем процессорного времени, например 20 минут, автоматически применяется вызов nice [4]. Схема, введенная в BSD 4.3, рассмотрена в [6]. Дальнейшее изложение в данном разделе статьи будет ориентировано на Unix System V. Как значение nice, так и значение динамического приоритета для процессов можно определить из вывода команды ps -l. Эти значения приводятся в колонках, озаглавленных NI и PRI соответственно.

Здесь можно провести некоторую аналогию с языком управления заданиями в ОС MVS. Параметр PRTY оператора EXEC является в определенном смысле аналогом nice: от их значений зависит динамический приоритет. Однако "настоящий" приоритет выполнения в MVS может быть задан параметром DPRTY, хотя и этот приоритет MVS может динамически изменить.

Планировщик Unix поддерживает фактически несколько циклических (round robin) очередей c обратной связью. Процесс, квант времени которого истек, возвращается в зависимости от динамического приоритета в одну из таких очередей, весь набор которых называют "очередью выполнения" (run queue).

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

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

Когда процесс "отправляется спать", планировщик присваивает ему фиксированный приоритет в зависимости от причины засыпания, который не зависит от наблюдавшейся перед этим событием активности "поедания" процессом процессорных ресурсов. Дополнительные подробности можно найти в [7].

Динамические приоритеты процессов, работающих в пользовательском режиме, перевычисляются планировщиком Unix System V один раз в секунду [7]. Обработчик прерываний от часов может прерывать пользовательский процесс несколько раз за его квант времени. Каждый раз при обработке такого прерывания счетчик "С" использования процессора в соответствующей строке таблицы процессов увеличивается на 1. Каждую секунду обработчик прерываний от часов пересчитывает счетчик использования процессора для каждого пользовательского процесса по формуле

С=С*k (8)

где 0<k<1; для System V k=0.5. Далее для каждого прерванного, но готового к выполнению пользовательского процесса динамический приоритет dprty рассчитывается по формуле

dprty=K*C + базовый_приоритет + nice (9)

где базовый_приоритет - это указанное пороговое значение приоритета пользовательских процессов (более приоритетными бывают только системные процессы). Константа К для System V равна 0.5. Близкие к (8), (9) алгоритмы использует Digital Unix. Чем ниже величина dprty динамического приоритета процесса, тем выше его приоритетность. Самая низкая величина dprty отвечает пороговому значению, ниже которого располагаются только системные процессы, работающие в режиме ядра.

В результате перерасчета dprty, пользовательские процессы, активно использующие процессор перемещаются из очереди с одним приоритетом в очереди с другим, более высоким dprty (в очереди менее приоритетных процессов). Чтобы понять, как работает механизм перерасчета динамических приоритетов в соответствии с формулами (8) и (9), рассмотрим конкретный пример, взятый из [7] для простейшего случая nice=0. Пусть имеется три готовых к выполнению процесса A, B, C, находящихся в памяти и имеющих стартовое значение приоритета, равное базовому значению (60), - максимально возможную приоритетность. Предположим, что эти процессы не делают системных вызовов и что в системе нет других готовых к выполнению процессов. Пусть квант времени равен 1 сек, а прерывания от часов происходят 60 раз за 1 сек.

Если A начинает выполняться первым, то через 1 сек его счетчик использования процессора будет равен 60. В этот момент времени планировщик пересчитает dprty (рис.1), и далее будет выполняться процесс B, а его счетчик использования процессора будет возрастать. При t=2 cек управление получит наиболее приоритетный процесс С и т. д.

Особенности планировщиков некоторых версий Unix

Как уже было показано, различные реализации Unix имеют свои особенности в работе с командой nice. Многие реализации отличаются существенными модификациями схемы работы с приоритетами. В качестве примера можно указать планировщик ОС AIX, в котором величины динамических приоритетов колеблются в диапазоне от 0 до 127. В AIX имеется специальная утилита schedtune, которая позволяет изменять некоторые параметры планировщика, в том числе и величину кванта времени. В последней, четвертой версии AIX, в schedtune появились и иные параметры [5].

В качестве другого примера можно подробнее рассмотреть некоторые возможности OC IRIX 6.1 и 6.2. Следующая команда IRIX 6.1/6.2 позволяет изменять некоторые параметры планировщика:

(10)#npri [-h ndpri] [-n nice] [-t slice] [-d период, объем] [-D only ] процесс any

Рисунок 1. Зависимость dprty от времени (чем выше dprty, тем ниже приоритетность). С - счетчик использования процессора.

где процесс задается своим идентификатором или явно указывает, какую команду нужно выполнить с этими параметрами планировщика:

процесс ::= команда аргументы_команды

-p pid

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

-h npri задает неизменный приоритет - приоритетность, не уменьшающуюся во времени. Аргумент npri лежит в диапазоне от 30 до 255, включая границы. Диапазон от 40 до 127 включительно относится к обычным интерактивным процессам разделения времени. Группа более приоритетных процессов имеет более низкое значение приоритета - от 30 до 39. С ними надо работать очень осторожно: обычный интерактивный процесс разделения времени не может их прервать. Диапазон от 127 до 255 относится к процессам низкой приоритетности - они могут использовать процессор, только если в системе нет "обычных", готовых к выполнению процессов.

  • -n nice задает значение nice в диапазоне от 0 до 39 включительно.

  • -t slice задает квант времени в единицах "тиков" часов (обычно 10 мсек)

  • -d период, объем устанавливает режим периодического планирования типа deadline. В этом режиме процессу гарантируется выделение определенного объема времени процессора (мсек) в каждый период времени, задаваемый аргументом период (мсек).

  • -D only(any) "уточняет" режим планирования типа deadline.

Если задано only, то после исчерпания объема гарантированного процессорного времени процесс не сможет в заданный период претендовать на дополнительное время процессора. Если указано any (по умолчанию), то и после исчерпания гарантированного объема времени процесс будет еще пытаться конкурировать за процессорные ресурсы с другими процессами, но уже на основании обычного режима планирования.В качестве приложений, для которых целесообразно указать гарантированное обслуживание процессором, можно упомянуть задачи визуализационного моделирования, работу с "непрерывными средами" на DAT или CD-ROM и др. Для работы с процессами реального времени в файловой системе xfs в ОС IRIX также имеется возможность поддержания гарантированной обработки подсистемой ввода/вывода. В ОС IRIX 6.х есть системный вызов schedctl, который использует команда npri.

Процессы реального времени и их планирование в Unix

В некоторых более ранних реализациях System V предусмотрена поддержка процессов реального времени через nice. Для этого суперпользователю приходилось запускать необходимые для работы в реальном времени задания с очень низкими значениями nice (-20 или ниже) [4]. Однако можно сказать, что полная поддержка процессов реального времени появилась только в Unix SVR4. Включение поддержки процессов реального времени в планировщик Unix SVR4 следует считать одним из самых кардинальных изменений в этом компоненте ядра Unix. POSIX 1003.1b описывает стандарт на средства реального времени.

Если интерактивные процессы разделяют процессорное время между собой, то процессы реального времени нуждаются в монополизации процессорного ресурса. Процессы реального времени могут прерывать интерактивные процессы разделения времени, но не наоборот. Если процесс реального времени монополизировал и не отдает процессор, то убить его с терминала из обычной оболочки, работающей в классе разделения времени, не удастся. Процессы реального времени имеют фиксированные приоритеты. Обычно работать с процессами реального времени на компьютере общего назначения не рекомендуется [4].

В Unix SVR4 все процессы делятся на три основных класса в соответствии с их глобальным приоритетом: класс процессов реального времени (RT), класс системных процессов и класс процессов разделения времени (рис. 2). В Руководстве по ОС Solaris говорится о наличии еще и класса интерактивных процессов (IA), для которых целью планировщика является обеспечение хорошего времени ответа, в то время как для класса процессов разделения времени (TS) задача состоит в обеспечении хорошей пропускной способности вычислительной установки, но так, чтобы "не мешать" достижению хорошего времени ответа для процессов класса IA. Доступ к классу IA имеет только суперпользователь. Классы TS и IA разделяют общие параметры планировщика и не различаются между собой с точки зрения механизма планирования. В связи с этим здесь не имеет смысла выделять IA в отдельный класс - будем просто говорить об (общем) классе TS.

Упомянутые глобальные приоритеты имеют, наконец, "естественный" смысл: чем выше приоритет, тем выше приоритетность процесса. Пользователь может получить соответствующий диапазон приоритетов, выдав команду

(11)%priocntl -l

Для запуска команды на выполнение в реальном времени суперпользователь может ввести

(12)#priocntl -e -c RT -p приоритет команда

где -с RT задает класс (Real Time). Приоритет задает значение приоритета внутри класса процессов реального времени (от 0 до 59, рис. 2); умалчиваемое значение равно 0. Аналогичным образом можно запускать процесс в класс TS.

Следующая команда позволяет суперпользователю перевести существующий процесс в класс реального времени и установить ему приоритет:

(13)#priocntl -s -c RT -p приоритет -i pid n

-s означает "установить" (set) приоритет; -i pid n задает идентификацию процесса, чей pid равен n.

Аналогичным образом можно работать с процессами класса TS. В ключе -i указывается тип идентификации процессов, который может принимать значения pid, ppid, pgid, sid (session id), class, uid, gid, all. Эти обозначения говорят сами за себя. Последний аргумент в команде (13) может задаваться в виде списка разделенных пробелами значений, указывающих на конкретный процесс (или конкретные процессы).

Можно указать, чтобы все процессы определенного пользователя стали работать в реальном времени:

(14)#priocntl -s -c RT -p приоритет -i uid n

Однако при этом в реальном времени будет работать и пользовательская оболочка, что считается опасным [4]. Если необходимо перевести процесс реального времени в класс процессов разделения времени, то это можно сделать командой

(15)#priocntl -s -c TS -p приоритет -i pid n

Здесь приоритет, естественно, задает значение приоритета внутри класса процессов разделения времени - величину nice (0 по умолчанию). Команда priocntl является универсальным средством; с ее помощью можно изменять и приоритеты процессов разделения времени:

(16)%priocntl -s -c TS -p приоритет -i pid n

В качестве другого примера применения priocntl можно взять установку максимального уровня приоритета для определенного процесса из класса TS:

(17)#priocntl -s -m приоритет pid

Данная команда устанавливает (-s) максимальный (-m) приоритет для процесса с идентификатором pid. Это может быть полезно для ограничения возможности роста приоритета низкоприоритетных процессов, чтобы они не мешали распределению процессорного времени более высокоприоритетным интерактивным процессам. Вообще priocntl с ключом -s имеет опции, подобно -m, которые являются специфическими для каждого класса.

#scheduler table for RT RES=1000 100 # 0 100 # 1 ......... 100 # 5 90 # 6 90 # 7 ......... 10 # 58 10 # 59 #end of table

Первое, что любят делать многие системные администраторы, особенно молодые и горячие, - это устанавливать себе более высокую приоритетность, например подняв ее для своей оболочки. Ясно, что если поднять ее "до небес", да еще, например, сделать приоритет неуменьшающимся - то, скажем, при инсталляции какого-либо крупного пакета в период трансляции, которая бывает достаточно долгой, пользователи вряд ли будут счастливы. Это нарушение первого принципа: "Живи сам и дай жить другим".

Другая голубая мечта некоторых "крутых" системных администраторов - поменять какие-нибудь "хитрые" параметры, дабы добиться увеличения пропускной способности или уменьшения времени реакции интерактивных процессов. Поскольку современные версии Unix предоставляют в распоряжение системного администратора весьма гибкий и "утонченный" аппарат, не нужно забывать второй принцип: KISS (Keep It Simple, Stupid) - "будь попроще, дурачок". Это золотое правило всех программистов особенно важно при тонкой настройке параметров