Планирование обычных процессов
Каждый обычный процесс имеет свой статический приоритет, значение, используемое планировщиком для определения важности процесса по отношению к другим обычным процессам в системе. Ядро выражает приоритет обычного процесса числом в диапазоне от 100 (наивысший приоритет) до 139 (низший приоритет). Обратите внимание, что с увеличением этого значения приоритет понижается.
Новый процесс всегда наследует статический приоритет родителя. Однако пользователь может изменить статический приоритет процесса, которым владеет, передав некоторые "nice-значения" системным вызовам nice о и setpriority.
Базовый квант времени
Статический приоритет, по сути дела, определяет базовый квант времени процесса, т. е. продолжительность кванта времени, присваиваемого процессу,
когда он исчерпывает свой предыдущий квант. Статический приоритет и базовый квант времени связаны следующей формулой:
Легко видеть, что чем выше статический приоритет (то есть меньше его числовое значение), тем дольше длится базовый квант времени. В результате процессы с более высоким приоритетом обычно получают более продолжительные отрезки времени процессора по сравнению с низкоприоритетными процессами. приводятся статические приоритеты, базовые кванты времени и соответствующие nice-значения для обычных процессов, имеющих тот или иной приоритет.
Динамический приоритет и среднее время сна
Кроме статического приоритета, у обычного процесса есть еще и динамический. Это значение, лежащее в диапазоне от 100 (наивысший приоритет) до 139 (низший приоритет). Фактически именно динамический приоритет нужен планировщику при выборе следующего процесса для выполнения. Он связан со статическим приоритетом при помощи следующей эмпирической формулы:
динамический приоритет = .
= max (100, min (статический приоритет-бонус + 5, 139))
Бонус — это число от 0 до 10. Значения, меньшие пяти, являются, так сказать, штрафом, понижающим динамический приоритет, а значения, большие пяти — премия, повышающая динамический приоритет процесса. Бонус, в свою очередь, зависит от предыдущей истории процесса, а точнее, от среднего времени сна процесса.
Грубо говоря, среднее время сна — это среднее количество наносекунд, проведенных процессом в ожидании. Следует, однако, заметить, что это не среднее время работы за истекший интервал. Например, ожидание в состоянии task interruptible вносит вклад в среднее время сна, отличный от того, что вносит ожидание в состоянии task uninterruptible. Кроме того, среднее время сна уменьшается, пока процесс работает. Наконец, среднее время сна ни в коем случае не может превысить 1 с.
Кроме прочего, среднее время сна используется планировщиком для определения, следует ли считать данный процесс интерактивным или пакетным.
Точнее говоря, процесс считается интерактивным, если он удовлетворяет следующему соотношению:
динамический приоритет time_slice = (current->time_slice +1) » 1; current->time_slice »= 1;
Иными словами, количество тиков, оставшихся у родителя, делится пополам между родителем и потомком. Это делается, чтобы не позволить пользователям получить неограниченное время процессора с помощью следующего метода: родительский процесс создает процесс-потомок, выполняющий тот же код, а себя уничтожает; при удачно подобранном темпе создания новых процессов потомок всегда будет получать свежий квант времени до истечения кванта его родителя. Так вот этот программный трюк не работает, потому что ядро не поощряет ветвление. Аналогичным образом пользователь не сможет отхватить себе дополнительное процессорное время в ущерб другим пользователям, если запустит несколько фоновых процессов из оболочки или откроет множество окон на графическом рабочем столе. Обобщая, можно сказать, что процесс не может заполучить ресурсы (если у него нет привилегии назначить самому себе политику реального времени), создавая многочисленное потомство.
Если у родителя в кванте остается всего один тик, в результате операции разделения в поле current->time_siice будет записан ноль, и квант родителя будет исчерпан. В этом случае функция copy process о записывает 1 в поле
current->time_slice И ВЫЗЫВает функцию scheduler tick , которая ЭТО ПОЛе уменьшает.
Кроме того, функция copy process о инициализирует некоторые другие поля дескриптора процесса-потомка, имеющие отношение к планированию:
p->first_time_slice = 1; p->timestamp = sched_clock;
Здесь устанавливается флаг first time siice, потому что потомок еще ни разу не исчерпал свой квант времени (если процесс закончится или выполнит новую программу в течение своего первого отрезка времени, то остаток отрезка времени, принадлежащего потомку, предоставляется родителю). Поле timestamp инициализируется отметкой времени, возвращенной функцией sched ciock : в сущности, эта функция возвращает содержимое 64-разряд- ного регистра TSC, преобразованное в наносекунды.
Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | Следующая страница