Некоторые знания ядра Linux (вкл.)

Операционная система Linux
Некоторые знания ядра Linux (вкл.)

предисловие

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

юникс система

В 1969 году в Bell Labs была рождена Unix, разработанная из неудачной операционной системы multis, и она была выпущена с исходным кодом, так что многие организации продолжали ее улучшать. Он написан на языке C и имеет всего несколько сотен системных вызовов, придерживаясь идеи дизайна, что все является файлом.

линукс система

Разработан финским студентом колледжа Линусом в 1991 году на основе микропроцессора Intel80386, исходный код был размещен в Интернете после разработки. Он основан на многих дизайнерских идеях Unix, но его реализация совершенно другая, и это другая операционная система. Соглашение об открытом исходном коде очень бесплатное и может свободно изменяться, но пересмотренный исходный код должен быть выпущен.

возможности линукса

  • Это одно ядро, а не микроядро.
  • Модульная конструкция, поддерживает динамическую загрузку модулей ядра.
  • Поддержка симметричного многопроцессорного механизма (SMP), несколько процессоров должны учитывать проблему общих ресурсов.
  • В вытесняющей многозадачной операционной системе планирование процессов ядром является вытесняющим.
  • Потоки ядра поддерживаются, но он не различает потоки и процессы, все процессы для него одинаковы.

что такое операционная система

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

Статус активности ЦП

  • Запускается в пользовательском пространстве и выполняет пользовательские процессы.
  • Запуск в пространстве ядра в контексте процесса означает выполнение процесса.
  • Работает в пространстве ядра, в контексте прерывания, в данный момент не имеет ничего общего с процессом задачи, он обрабатывает прерывание.

Процесс и поток

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

Ядро сохраняет все процессы в очереди задач, которая представляет собой дважды циклический связанный список Типом каждого узла в связанном списке является структура дескриптора процесса task_struct, расположенная в .

Все процессы являются потомками процесса init, у которого PID равен 1. Процесс init запускается на заключительном этапе запуска ядра, который отвечает за чтение сценария инициализации системы и выполнение других связанных программ. У каждого процесса есть родительский процесс, и каждый процесс также может иметь ноль или более дочерних процессов. fork() используется для создания дочернего процесса.Он создает дочерний процесс, копируя текущий процесс.Разница между родительским и дочерним процессами заключается в PID, PPID, определенных ресурсах и статистике. fork() использует механизм копирования при записи, родительский процесс и дочерний процесс совместно используют одну и ту же копию, и данные будут скопированы только тогда, когда их необходимо записать. Фактические накладные расходы fork() копируют родительскую таблицу страниц и создают уникальный дескриптор процесса для дочернего процесса. exec() отвечает за чтение исполняемого файла и загрузку его в пространство для запуска. Процесс завершается, когда процесс вызывает системный вызов exit().

Поток — это активный объект процесса, и каждый поток имеет независимый счетчик программ, стек процесса и набор регистров. Потоки могут совместно использовать адресное пространство памяти, совместно использовать файлы и другие ресурсы в рамках одной и той же программы. С точки зрения ядра, в Linux нет концепции потоков, он рассматривает потоки как процессы. Потоки ядра не имеют независимого адресного пространства, они работают только в пространстве ядра и никогда не переключаются в пространство пользователя.

планирование процесса

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

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

стратегия планирования

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

Планирование на основе приоритетов — это самый простой алгоритм планирования, который классифицирует процессы: процессы с более высоким приоритетом запускаются первыми, процессы с более низким приоритетом запускаются позже, а процессы с одинаковым приоритетом запускаются по очереди. Высокоприоритетные процессы в некоторых системах будут выполняться чаще и с более длительными интервалами времени. Планировщик выбирает для выполнения процесс, временной интервал которого не исчерпан и имеет наивысший приоритет. В Linux есть два диапазона приоритета, первый — значение nice, от -20 до +19, по умолчанию 0, чем больше значение, тем ниже приоритет. Второй — это приоритет в реальном времени.Диапазон по умолчанию — от 0 до 99. Чем выше значение, тем выше приоритет. Приоритет любого процесса реального времени выше, чем у обычных процессов, а это означает, что хороший приоритет и приоритет реального времени — это два разных измерения.

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

Планировщик CFS

Linux использует алгоритм Completely Fair Scheduling (CFS), который является планировщиком для обычных процессов.Он называется SCHED_NORMAL в Linux и SCHED_OTHRER в POSIX.Класс реализации находится в kernel/sched_fair.c. CFS позволяет каждому процессу выполняться в течение определенного периода времени, вращаться в цикле и выбирать наименее запущенный процесс в качестве запускаемого процесса.CFS вычисляет общее количество всех запущенных процессов в качестве основы, а затем вычисляет, как долго процесс должен работать, вместо того, чтобы вычислять кванты времени по приоритету. CFS имеет минимальный квант времени (минимальную степень детализации), который по умолчанию составляет 1 мс. То есть, даже если есть бесконечные процессы, каждый процесс может иметь временной интервал не менее 1 мс. CFS гарантирует, что каждому процессу предоставляется справедливое соотношение использования процессора.

  • CFS больше не просто использует концепцию квантов времени, но должна поддерживать учет времени каждого запущенного процесса, чтобы обеспечить справедливое распределение каждого процесса.
  • Когда CFS выбирает следующий процесс для запуска, он выбирает процесс с наименьшим временем выполнения.
  • Спящий (заблокированный) процесс находится в неисполняемом состоянии, он будет удален из исполняемого красно-черного дерева и помещен в очередь ожидания. Очередь ожидания представляет собой простую структуру связанного списка,
  • Для пробуждения, противоположного сну, процесс устанавливается в исполняемое состояние и перемещается из очереди ожидания в исполняемое красно-черное дерево.
  • Переключение контекста, то есть переключение с одного исполняемого потока на другой исполняемый процесс, отвечает функция context_switch ядра/sched.c. Сопоставьте виртуальную память из предыдущего процесса с новым процессом, сохраните информацию о стеке восстановления, информацию о регистрации и другую связанную информацию.
  • Ядро предоставляет флаг need_resched, чтобы указать, нужно ли ему повторно выполнить планирование. Ядро проверит эту песню, прерывает ли она обработчик или возвращает после системного вызова. Если он установлен, ядро ​​выберет более подходящий процесс бежать.

планирование в реальном времени

Linux предоставляет две стратегии планирования в реальном времени: SCHED_FIFO и SCHED_RR. Первый представляет собой простой алгоритм планирования FIFO, который не использует временные интервалы. Процессы на уровне SCHED_FIFO будут запланированы перед любыми процессами на уровне SCHED_NORMAL. Как только процесс на уровне SCHED_FIFO становится исполняемым, он будет выполняться до тех пор, пока не заблокирует себя или явно не освободит ЦП. Его могут вытеснить только процессы SCHED_FIFO или SCHED_RR с более высоким приоритетом. Два процесса уровня SCHED_FIFO с одинаковым приоритетом будут выполняться по очереди, а другие обычные процессы могут иметь шанс на выполнение только после того, как он станет неработоспособным.

SCHED_RR примерно такой же, как SCHED_FIFO, но он не продолжает выполняться по истечении предварительно выделенного времени, то есть SCHED_RR — это SCHED_FIFO с временным интервалом. Квант времени относится только к процессу с таким же приоритетом, и процесс с низким приоритетом не может вытеснить задачу SCHED_RR, даже если его квант времени исчерпан.

отказаться от процессорного времени

Linux использует системный вызов sched_yield(), чтобы передать процессорное время текущего процесса другим ожидающим выполнениям.Для процессов реального времени он переместит процесс из активной очереди в конец приоритетной очереди. Семантика yield раннего Linux другая, только процесс будет поставлен в конец приоритетной очереди, и время, чтобы сдаться, не будет слишком долгим.

Сосредоточьтесь на искусственном интеллекте, чтении и мышлении, расскажите о математике, информатике, распределенных технологиях, машинном обучении, глубоком обучении, обработке естественного языка, алгоритмах и структурах данных, глубине Java, ядре Tomcat и т. д.