Подтвердить что ты не робот

Шаги в контекстном переключении

Мне предлагается описать шаги, связанные с переключателем контекста (1) между двумя различными процессами и (2) между двумя разными потоками в одном процессе.

  • Во время переключения контекста ядро ​​будет сохранять контекст старого процесса на его PCB, а затем загружать сохраненный контекст нового процесса, который планируется запустить.
  • Контекстное переключение между двумя разными потоками в одном и том же процессе может быть запланировано операционной системой, так что они будут выполняться параллельно и, как правило, быстрее, чем контекстные переключатели между двумя различными процессами.

Это слишком общее или что бы вы добавили, чтобы объяснить процесс более понятным?

4b9b3361

Ответ 1

Это намного проще объяснить в обратном порядке, потому что в коммутаторе процесса всегда есть переключатель потоков.

Типичный контекстный коммутатор потока на одноядерном CPU происходит следующим образом:

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

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

  • Состояние ядра для прерванного потока должно быть сохранено. В простой встроенной системе это может просто подтолкнуть все регистры к стеку потоков и сохранить указатель стека в его блоке управления потоками (TCB).

  • На этом этапе многие системы переключаются на выделенный ОС, так что основная часть требований к внутреннему стеку OS не наносится на стек каждого потока.

  • Может потребоваться отметить позицию стека потоков, в которой произошло изменение состояния прерывания, чтобы разрешить вложенные прерывания.

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

  • Алгоритм планировщика ОС запускается, чтобы решить, какой поток будет выполняться дальше, как правило, самый высокий приоритетный поток, который находится в передней части очереди для этого приоритета. Если поток next-to-run принадлежит другому процессу к предыдущему потоку, здесь требуется дополнительная информация (см. Ниже).

  • Сохраненный указатель стека из TCB для этого потока извлекается и загружается в указатель аппаратного стека.

  • Состояние ядра для выбранного потока восстанавливается. В моей простой системе регистры будут выгружаться из стека выбранного потока. Более сложные системы должны будут обрабатывать возврат к защите на уровне пользователя.

  • Выполняется прерывание, поэтому передача выполнения в выбранный поток.

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

Типичный переключатель контекста процесса происходит следующим образом:

  • Переключатели контекста процесса инициируются переключателем контекста потока, поэтому все вышеперечисленное, 1-9, должно произойти.

  • На шаге 5 выше планировщик решает запустить поток, принадлежащий другому процессу, из того, который принадлежал ранее работающему потоку.

  • Аппаратное обеспечение управления памятью должно быть загружено адресным пространством для нового процесса, то есть любыми селекторами/сегментами/флагами/тем, что позволяют потоку /s нового процесса получить доступ к его памяти.

  • Контекст любого оборудования FPU должен быть сохранен/восстановлен с печатной платы.

  • Может быть другое оборудование, предназначенное для обработки, которое необходимо сохранить/восстановить.

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

Ответ 2

Я надеюсь, что я смогу предоставить более подробную/четкую картину.

Во-первых, OS планирует потоки, а не процессы, потому что потоки являются единственными исполняемыми единицами в системе. Переключатель процессов - это просто переключатель потоков, в котором потоки относятся к разным процессам. В связи с этим в общем случае процедура переключения обычна.

  • Следует использовать планировщик. Существуют три основных сценария:

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

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

  • Первое действие, которое выполняет ядро, - это сохранение содержимого регистров процессора, которое ядро ​​будет повторно использовать для своих собственных задач. Обычно ядро ​​использует только регистры CPU общего назначения и сохраняет их путем нажатия в стек.
  • Затем ядро ​​обрабатывает первичный запрос - прерывание дескриптора или готовит запрос на чтение файла или выполняет настройку таймера.
  • В какой-то момент обработки запроса ядро ​​выполняет действие, которое влияет на состояние текущего потока (решил, что в этом потоке ничего не стоит, и мы должны ждать чего-то) или повлиять на состояние другого потока (потоков) (новый поток стал управляемым в результате приема прерывания или из-за выпущенного мьютекса и т.д.).
  • Ядро вызывает планировщик. Планировщик должен принять два решения. Сначала речь идет о том, что делать с текущей нитью. Должен ли он быть заблокирован? Если да, то в какую очередь ожидания нужно поместить? Если поток переключается непроизвольно, он помещается в конец runqueue, если поток заблокирован, потому что он ждет somethins, он помещается в один из ожидающих событий. Второе решение - о том, какой поток будет выполняться дальше.
  • Как только оба решения принимаются, scheduller выполняет контекст swicth, передавая ему два параметра - блок управления потоком текущего и следующего потоков.
  • Контекстный коммутатор состоит из трех основных этапов. На первом ядро ​​вычисляет, какой процессор регистрирует поток, который фактически использует, и сохраняет их содержимое как в стеке, так и в TCB потока с перераспределением. Если поток не использует регистры FPU и SSE (exaple для платформы IA-32), их содержимое не будет сохранено.
  • Второй шаг - это сердце переключателя контекста. Ядро подталкивает указатель текущей инструкции к стеку, а значение указателя стека сохраняет TCB исходящего потока. Затем он загружается в новый указатель стека процессора из TCB входящего потока и указателя инструкции pops сверху. Это! Новый активный стек означает новый активный поток. Начиная с этого момента остальная часть системы будет думать, что она работает в контексте входящего потока.
  • На третьем этапе ядро ​​выясняет, какие регистры фактически используются входящим потоком и загружает их ранее сохраненный контент (см. шаг 1) обратно в ЦП.
  • Затем проверка ядра делает оба потока (входящие и исходящие) принадлежащими к одному и тому же процессу или нет. Если они принадлежат к разным процессам (случай, когда люди называют процесс переключения), ядро ​​ reset текущее адресное пространство, указывающее MMU на новый набор таблиц преобразования виртуального на физический адрес. В рамках этого процесса CPU сбрасывает Translate Lookaside Buffer (TLB), который кэширует виртуальные правила управления физическими адресами. Новое виртуальное адресное пространство означает, что ранее кэшированные правила теперь неверны. Обратите внимание, что это единственный шаг во всем наборе действий переключателя контекста, который заботится о процессах!
  • Ядро готовит локальное хранилище потоков для входящего потока. Например, сопоставление соответствующих страниц памяти с указанными адресами или, например, по общему подходу IA-32 - это загрузка нового сегмента, который указывает на данные TLS входящего потока.
  • Наконец, ядро ​​загружается в адрес процессора части ядра входящего потока. После этого каждый новый вызов ядра будет использовать часть ядра входящего потока и не повредит данные, хранящиеся в стеке исходящего потока.
  • Другим шагом, который может выполнять ядро, является перепрограммирование системного таймера. Выполнение этого ядра запрашивает таймер для вызова и передачи управления ядру через некоторое время. Этот период времени называется квантом времени потока.
  • Наконец, ядрам нравится собирать статистику при переключении контекста, включая информацию о soch, о том, сколько потоков времени процессора потребляет, как могут переключаться контексты в системе в единицу реального времени, сколько раз были задействованы потоки, сколько раз они имеют выпущенный ЦП, добровольный и непроизвольный, сколько раз у них закончились кванты. Часть этой статистики используется тогда планировщиком, что позволяет принимать более оптимальные решения. Другая цель статистики - предоставить системным администраторам и пользователям возможность показать им, что происходит под капотом системы.
  • Режиссер потоков можно считать выполненным в этой точке, и ядро ​​продолжает прерванные действия системы. Например, поток, ожидающий чтения файла, проверяет результат чтения в памяти и обрабатывает его. Или поток, который был заблокирован на мьютексе в середине некоторой большой активности системы, продолжает эту активность.
  • Наконец, позже или раньше поток завершает работу системы и хочет вернуться в пользовательский режим, чтобы продолжить свою основную задачу, для которой она была первоначально использована. На этом этапе ядро ​​выскакивает из содержимого стека ядра общих регистров, которое ранее было сохранено во время ввода в ядро, и просит CPU выполнить возврат в пользовательский режим.
  • CPU фиксирует значения указателя инструкции и указателя стека, которые ранее были сохранены во время входа в режим ядра и восстанавливали их. Выполняя это, он также переключает поток обратно из части ядра своего стека в пользовательскую часть стека. Наконец, CPU сбрасывает разрешения кода, который будет выполняться с более ограниченным набором (запрещает использование специальных системных инструкций, например, или запрещает доступ к кодерному коду и данным). Наконец, CPU передает управление обратно в точку, в которой поток был первоначально выгружен. В случае системного вызова поток будет продолжаться в точке, где был вызван системный вызов, путем захвата и обработки его результата. В случае прерывания прерывания поток продолжит выполнение только в том же месте, в котором произошло прерывание. В этом случае он даже не будет полностью знать, что он был прерван.

Некоторые сводные примечания:

  • Ядро расписания и выполняет только потоки, а не процессы. Из-за этого контекста swicth происходит между потоками.
  • Процедура переключения контекста между протекторами, принадлежащими разным процессам, по существу такая же, как между потоками, принадлежащими к одному и тому же процессу. В первом случае есть только один дополнительный шаг - загрузка нового виртуального адресного пространства (что приводит к отключению TLB).
  • Контекст потоков сохраняется либо в части ядра стека нити, либо в потоке TCB (не в PCB!).
  • Потоковый переключатель вводит штраф за производительность. Существует значительная прямая стоимость переключения потоков. И даже намного большая стоимость inderect, созданная загрязнением кэша и сбросом TLB (если виртуальное адресное пространство было перезагружено во время переключения).

Ответ 3

  • В коммутаторе состояние процесса, которое в настоящее время выполняется, должно быть каким-то образом сохранено, так что, когда оно будет перенесено, это состояние может быть восстановлено.
  • Состояние процесса включает в себя все регистры, которые может использоваться процессом, особенно счетчик программ, а также любые другие конкретные данные операционной системы, которые могут потребоваться. Обычно это хранится в структуре данных, называемой блок управления процессом (PCB) или коммутатор.
  • PCB может храниться в стеке каждого процесса в памяти ядра (в отличие от стека вызовов пользовательского режима), или для этой информации может быть определенная определенная операционная система. Ручка к PCB добавляется в очередь процессов, которые готовы к запуску, часто называемые готовой очередью.
  • Так как операционная система эффективно приостановила выполнение одного процесса, он может переключать контекст, выбирая процесс из очереди готовности и восстанавливая свою печатную плату. При этом загружается счетчик программ с печатной платы, и поэтому выполнение может продолжаться в выбранном процессе. Приоритет процесса и потока может влиять на то, какой процесс выбран из готовой очереди (т.е. Это может быть очередь приоритетов).

Context Switch

(Источник: Контекстный контекст)

Ответ 4

1. Сохраните контекст процесса, который в данный момент выполняется на процессоре. Обновите блок управления процессом и другие важные поля.

2. Переместите блок управления процессом вышеупомянутого процесса в соответствующую очередь, такую как очередь готовности, очередь ввода-вывода и т.д.

3. Выберите новый процесс для исполнения.

4. Обновите блок управления процессом выбранного процесса. Это включает в себя обновление состояния процесса на выполнение.

5. При необходимости обновите структуры данных управления памятью.

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