Unix - система с разделением времени, поэтому время центрального процессора выделяется процессам квотами. Отличительной особенностью является то, что при выделении времени ЦП основным критерием является уже использованное процессом процессорное время. С каждым процессом связано понятие приоритета и использованного времени ЦП. Для хранения этих величин в СТП имеются специальные поля: PRTY, CPU.
У пользовательских процессов приоритет периодически пересчитывается, причем при этом пересчете учитывается поле CPU. Обычно пересчет приоритета для пользовательских процессов происходит при переходе процесса из системного в пользовательский режим, а также периодически раз в секунду.
В Unix используется круговая многоуровневая диспетчеризация, согласно которой планировщик планирует загрузку процессора следующим образом:
после истечения квоты времени, выделенной процессу, его выполнение приостанавливается, если он до этого не был приостановлен или сам не перешел в режим ожидания, контекст процесса сохраняется и он переходит в конец очереди своего приоритета.
|
|
из очереди готовых процессов выбирается наиболее высокоприоритетный, его контекст восстанавливается и запускается на выполнение.
если имеется несколько процессов с одинаковым приоритетом, то выбирается тот, который ждет дольше (поле CPU которого меньше).
Если в системе не ни одного готового процесса, планировщик переходит в состояние ожидания, и повторяет попытку планирования при следующем тике таймера или операции прерывания.
Все приоритеты в системе разбиты на 2 класса:
Системные
Пользовательские
Внутри каждого из классов существуют уровни приоритетов.
Пользовательские уровни приоритета используются для процессов, работающих в пользовательском режиме, системные уровни – для процессов в системном режиме.
Процессы, работающие в системном режиме, не могут прерываться планировщиком и работают, пока сами не перейдут в ожидание. Их приоритеты при этом устанавливаются в зависимости от того, какого события они ждут. Наивысшим приоритетом обладают процессы, ожидающие свопинга и т.д. При переходе процесса из системного режима в пользовательский, его приоритет пересчитывается по правилам пересчета пользовательских приоритетов.
При работе в пользовательском режиме для пересчета готовых пользовательских процессов планировщик выполняет следующие действия:
|
|
при каждом прерывании от таймера планировщик добавляет единицу в поле CPU активного процесса.
каждую секунду для всех готовых процессов планировщик выполняет следующие вычисления:
CPU=CPU/2
PRTY=CPU/2 + PUSER + [nice]
PUSER – граничный приоритет, чем больше PRTY, тем ниже приоритет процесса.
По этому же правилу происходи пересчет приоритета процесса, когда он переходит из системного в пользовательский. Обычно планировщик имеет маску, в которой для каждого уровня приоритета отводиться по 1 биту. Он устанавливается в 1, если в очереди готовых процессов есть процесс с данным уровнем приоритета и в 0, если таковых нет.
Планирование Unix.
Пусть есть 3 готовых процесса A,B,C. Они запущены в этом порядке, пограничный приоритет PUSER=60. Количество тиков в секунду – 60. Планировщик выполняет планирование по формулам: CPU=CPU/2, PRTY=CPU/2+PUSER.
В Unix есть специальная команда: nice имя m. С ее помощью можно запускать программы и изменять их приоритет на некоторую величину m. Приоритет для задач запущенных с помощью nice вычисляется как: PRTY=CPU/2 + PUSER + m.
Обычно пользователь в команде nice может использовать m>0, т.е. он может только увеличить PRTY (уменьшить приоритет). Суперпользователь может задавать m<0, т.е. увеличивать приоритет. Существует команда позволяющая изменить приоритет выполняющегося процесса: renice PID m.
С помощью команды setpri() можно явно назначить уровень приоритета выполнения процесса. Если при этом приоритет становиться больше граничного, т.е. попадает системный класс, то процесс уже не будет прерываться планировщиком и будет выполняться по правилам процессов, работающих в системном режиме.