Что значит сказать «ядро linux превентивное»? - PullRequest
27 голосов
/ 12 марта 2011

Я читал, что ядро ​​Linux является преимущественным, что отличается от большинства ядер Unix. Итак, что же на самом деле означает, что кернал должен быть упреждающим?

Некоторые аналогии или примеры были бы лучше, чем чисто теоретическое объяснение.

ADD 1 - 11:00 AM 12/7/2018

Упреждающий - это всего лишь одна парадигма многозадачности. Есть и такие, как Совместная многозадачность . Лучшего понимания можно достичь, сравнив их.

Ответы [ 9 ]

24 голосов
/ 12 марта 2011

До версии ядра Linux 2.5.4 ядро ​​Linux не было вытесняющим, что означает, что процесс, работающий в режиме ядра, не может быть перемещен из процессора, пока он сам не покинет процессор или не начнет ожидать завершения какой-либо операции ввода-вывода.

Обычно процесс в пользовательском режиме может войти в режим ядра с помощью системных вызовов. Ранее, когда ядро ​​не было вытесняющим, процесс с более низким приоритетом мог инвертировать процесс с более высоким приоритетом, отказывая ему в доступе к процессору путем повторного вызова системных вызовов и оставаясь в режиме ядра. Даже если временной интервал процесса с более низким приоритетом истек, он продолжит работать, пока не завершит свою работу в ядре или добровольно не откажется от управления. Если процесс с более высоким приоритетом, ожидающий запуска, является текстовым редактором, в котором пользователь печатает, или MP3-плеером, готовым пополнить свой аудио-буфер, результатом будет плохая интерактивная производительность. Таким образом, неперегрузочное ядро ​​в то время было основным недостатком.

18 голосов
/ 12 марта 2011

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

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

В старых ядрах Linux никогда не разрешалось прерывать задачу, пока она была занята выполнением кода ядра. (Обратите внимание, что операции ввода-вывода всегда добровольно планируются. Я говорю о случае, когда в коде ядра выполняются некоторые ресурсоемкие операции, такие как сортировка списка.)

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

Например, если на конкретном процессоре доступно две задачи, и для выполнения одной из них требуется системный вызов, выполнение которого занимает 5 мс, а для другой - приложение MP3-плеера, которому необходимо подавать аудиоканал каждые 2 мс, вы можете услышать заикание звук.

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

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

7 голосов
/ 12 марта 2011

Традиционные ядра Unix имели одну блокировку, которая удерживалась потоком во время работы кода ядра. Поэтому никакой другой код ядра не может прервать этот поток.

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

В однопроцессорных системах это не вызывает особых проблем.

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

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

5 голосов
/ 12 марта 2011

Выгрузка позволяет ядру создать ВПЕЧАТЛЕНИЕ параллелизма: у вас есть только один процессор (скажем, десять лет назад), но вы чувствуете, что все ваши процессы работают одновременно. Это происходит потому, что ядро ​​прерывает (то есть выводит выполнение) выполнение из одного процесса, чтобы передать его следующему (возможно, в соответствии с их приоритетом).

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

РЕДАКТИРОВАТЬ 2 Основная цель вытеснения заключается в повышении реактивности системы среди множества задач, что хорошо для конечных пользователей, тогда как с другой стороны, серверы хотят достичь максимальной производительности. так что им это не нужно: (из конфигурации ядра Linux)

3 голосов
/ 12 марта 2011

Это означает, что планировщик операционной системы может свободно приостанавливать выполнение запущенных процессов, чтобы передавать ЦП другому процессу в любое время; Обычный способ сделать это - дать каждому процессу, ожидающему ЦП, «квант» времени ЦП. По истечении этого срока планировщик забирает управление (и запущенный процесс не может этого избежать), чтобы передать другой квант другому процессу.

Этот метод часто сравнивают с кооперативной многозадачностью, в которой процессы сохраняют ЦП в течение всего необходимого времени, не прерываясь, и чтобы другие приложения могли работать, они должны явно вызывать какую-то функцию «yield»; естественно, чтобы избежать ощущения застревания системы, хорошо работающие приложения будут часто приводить к загрузке ЦП. Тем не менее, если в приложении есть ошибка (например, бесконечный цикл без вызовов yield), вся система зависнет, так как ЦП полностью сохраняется неисправной программой.

Почти все последние настольные ОС используют многозадачность с вытеснением, которая, даже если она дороже с точки зрения ресурсов, в целом более стабильна (более сложному приложению сложнее повесить всю систему, поскольку ОС всегда находится в контроль). С другой стороны, когда ресурсы ограничены и ожидается, что приложение будет вести себя хорошо, используется совместная многозадачность. Windows 3 была кооперативной многозадачной ОС; более свежим примером может служить RockBox, замена прошивки PMP с открытым исходным кодом.

2 голосов
/ 12 марта 2011

Ядро linux является монолитным и дает небольшую вычислительную длительность для всех запущенных процессов последовательно. Это означает, что процессы (например, программы) не работают одновременно, но им регулярно дается время для выполнения их логики. Основная проблема заключается в том, что некоторая логика может занять больше времени для завершения и не позволяет ядру выделить время для следующего процесса. В результате система "лагает".

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

Практически это означает, что ядро ​​способно решать задачи в режиме реального времени, что особенно интересно для записи и редактирования аудио.

Ubuntu Studio Districution упаковывает упреждающее ядро, а также пакет качественного бесплатного программного обеспечения, посвященного аудио и видео изданию.

1 голос
/ 07 марта 2019

Я думаю, что все хорошо объяснили это, но я просто добавлю немного больше информации.в контексте Linux IRQ - планировщик прерываний и ядра.

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

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

С другой стороны, планировщик без вытеснения не может отобрать ЦП у процесса (он же кооператив) К вашему сведению, слово «кооператив» может вводить в заблуждение, поскольку значение словане ясно указывает, что на самом деле делает планировщик.

Например, в старых Windows, таких как 3.1, были совместные планировщики.

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

0 голосов
/ 21 августа 2013

Ядро Linux является вытесняющим, что означает, что ядро ​​поддерживает вытеснение.

Например, есть два процесса P1 (более высокий приоритет) и P2 (более низкий приоритет), которые выполняют системные вызовы чтения, и они работают в ядре.Режим.Предположим, что P2 работает и находится в режиме ядра, а P2 запланирован для запуска.

Если доступно вытеснение ядра, то вытеснение может произойти на уровне ядра, то есть P2 может быть вытеснено, но для сна и P1 можетпродолжить работу.

Если выгрузка ядра недоступна, так как P2 находится в режиме ядра, система просто ждет, пока P2 завершится, а затем

0 голосов
/ 12 марта 2011

Я думаю, что это стало преимущественным с 2.6Упреждающий означает, что когда новый процесс готов к запуску, процессор будет выделен для нового процесса, ему не нужно, чтобы запущенный процесс был совместным и отказывался от процессора.

...