Linux Kernel (Ядро линукса) (часть 1)


Вытеснение в ядре

Удивительно, но дать хорошее определение для вытеснения в ядре очень трудно. С первой попытки можно сказать, что ядро реализует вытеснение, если переключение процессов может произойти, когда замещаемый процесс выполняет функцию ядра, т. е. работает в режиме ядра. К сожалению, в Linux (как и любой другой реальной операционной системе) все обстоит гораздо сложнее:
- как в вытесняющих, так и в невытесняющих ядрах процесс, работающий в режиме ядра, может добровольно освободить процессор, например, потому что ему приходится остановиться в ожидании некоторого ресурса. Такую ситуацию мы назовем запланированным переключением процессов. Однако вытесняющее ядро отличается от невытесняющего тем, как процесс, работающий в режиме ядра, реагирует на асинхронные события, которые могут привести к переключению процессов (пример такого события — обработчик прерываний будит процесс с более высоким приоритетом). Подобный вид переключения процессов мы назовем форсированным;
-все переключения процессов выполняются макросом switch to. Как в вытесняющих, так и в невытесняющих ядрах переключение процессов происходит, когда процесс закончил выполнять некоторый поток ядра, и вызван планировщик. Однако в невытесняющих ядрах текущий процесс не может быть замещен, если он не собирается в данный момент переключиться в режим пользователя.
Таким образом, главной характеристикой вытесняющего ядра является тот факт, что процесс, работающий в режиме ядра, может быть замещен другим процессом прямо в середине выполнения функции ядра.

Приведем пару примеров для иллюстрации разницы между вытесняющим и невытесняющим ядром

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

Основной целью реализации вытеснения в ядро является сокращение переходного состояния процессов режима пользователя, т. е. времени между моментом, когда процесс стал выполняемым, и моментом, когда он фактически стал выполняться. Процессы, выполняющие задачи, требующие точного планирования времени (контроллеры внешней аппаратуры, датчики состояния окружающей среды, видеоплееры и т. д.), реально выигрывают от вытеснения в ядре, поскольку уменьшается риск, что они будут задержаны другим процессом, работающим в режиме ядра.
Превращение ядра Linux в вытесняющее не потребовало резких изменений в схеме его работы по сравнению со старыми невытесняющими версиями. вытеснение в ядре отключено, если поле preempt count в дескрипторе thread info, на который ссылается макрос current thread infо , больше нуля.

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

Несколько простых макросов, , работают со счетчиком Вытеснений, храНЯЩИМСЯ В ПОЛе prempt_count.Макрос preempt enabie уменьшает счетчик вытеснений, а затем проверяет, установлен ли флаг tif need resched. В этом случае висит” запрос на переключение процессов, и поэтому макрос вызывает функцию preempt scheduie , которая фактически выполняет следующий код:
if (!current_thread_info->preempt_count && !irqs_aisabled()) { current thread info->preempt count = PREEMPT ACTIVE;
schedule();current_thread_info->preempt_count = 0;}
Функция проверяет, включены ли локальные прерывания, и равно ли нулю поле preempt count у текущего процесса. Если оба условия выполнены, она вызывает функцию schedule о, чтобы выбрать другой процесс. Таким образом, вытеснение в ядре может произойти либо когда прекращается выполнение управляющего тракта ядра (обычно это обработчик прерываний), либо когда обработчик исключения заново включает вытеснение с помощью макроса preempt enabie . Как мы увидим далее в разд. "Запрещение и разрешение функций отложенного выполнения" этой главы, вытеснение в ядре может также иметь место, когда включаются функции отложенного выполнения.
Мы завершим этот раздел замечанием о том, что вытеснение в ядре требует расходов, с которыми нельзя не считаться. По этой причине в Linux существует опция конфигурации ядра, позволяющая пользователям включать или выключать вытеснение при компиляции ядра.

Когда синхронизация необходима

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

Предыдущая страница | 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 | Следующая страница




Возможно, Вас также заинтересует:

ОС Knoppix - это Linux без про...

ВведениеЕсли вы цените свое время, умеете считать деньги и знаете стоимость информации, то эта книга...

Linux Kernel (Ядро линукса) (ч...

Спин-блокировкаСпин-блокировка необходима в многопроцессорной системе, потому что могут возникнуть...

Linux Kernel (Ядро линукса) (ч...

Копирование при записи В системах Unix первых поколений создание процесса было реализовано довольно...

Linux Kernel (Ядро линукса) (ч...

Буферы блоков и головы буферовУ каждого буфера есть дескриптор голова буфера, имеющий тип buffer...