Введение

Переключение между процессами или задачами на компьютере. Переключение задач на компьютере.

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

Стоимость

Контекстные переключения обычно вычислительно затратны, и значительная часть проектирования операционных систем направлена на оптимизацию их использования. Переход от одного процесса к другому требует определенного времени на административные операции: сохранение и загрузку регистров, карт памяти, обновление различных таблиц и списков и т.п. Что именно включает в себя переключение контекста, зависит от архитектуры, операционной системы и количества совместно используемых ресурсов (потоки, принадлежащие одному процессу, разделяют больше ресурсов, чем несвязанные некооперирующие процессы). Например, в ядре Linux переключение контекста включает загрузку соответствующего блока управления процессом (PCB), хранящегося в таблице PCB в стеке ядра, для получения информации о состоянии нового процесса. Информация о состоянии процессора, включая регистры, указатель стека и счетчик программ, а также информация об управлении памятью, такая как таблицы сегментации и таблицы страниц (если старый процесс не разделяет память с новым), загружается из PCB для нового процесса. Чтобы избежать некорректного преобразования адресов в случае использования разной памяти предыдущим и текущим процессами, буфер трансляции lookaside (TLB) должен быть очищен. Это негативно сказывается на производительности, поскольку после большинства переключений контекста каждая обращение к памяти в TLB будет приводить к промаху, так как он пуст. Кроме того, аналогичное переключение контекста происходит между пользовательскими потоками, в частности, "зелеными" потоками, и часто является очень легковесным, сохраняя и восстанавливая минимальный контекст. В крайних случаях, например, при переключении между горутинами в Go, переключение контекста эквивалентно уступке корутины, что лишь незначительно дороже вызова подпрограммы.

Многозадачность

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

Перерыв в обработке

Современные архитектуры основаны на прерываниях. Это означает, что если процессор запрашивает данные с диска, например, ему не нужно ожидать завершения чтения, постоянно проверяя его готовность; он может отправить запрос (устройству ввода-вывода) и продолжить выполнение другой задачи. Когда чтение завершено, процессор может быть прерван (в данном случае аппаратным обеспечением, которое посылает запрос на прерывание в PIC) и ему предоставляются прочитанные данные. Для обработки прерываний устанавливается программа, называемая обработчиком прерываний, и именно он обрабатывает прерывание, поступившее с диска. При возникновении прерывания аппаратное обеспечение автоматически сохраняет часть контекста (как минимум, достаточную для того, чтобы обработчик мог вернуться к прерванному коду). Обработчик может сохранить дополнительный контекст, в зависимости от особенностей конкретной аппаратной и программной реализации. Часто изменяется лишь минимальная часть контекста, чтобы минимизировать время, затрачиваемое на обработку прерывания. Ядро не запускает и не планирует специальный процесс для обработки прерываний, а обработчик выполняется в (часто частичном) контексте, созданном в начале обработки прерывания. После завершения обслуживания прерывания восстанавливается контекст, который был активен до возникновения прерывания, чтобы прерванный процесс мог возобновить выполнение в своем исходном состоянии.

Переключение на пользовательский и ядренный режимы

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

Шаги

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

Пример

Рассматривая общую арифметическую операцию сложения A = B + 1. Инструкция сохраняется в регистре команд, а счётчик программы увеличивается. Значения A и B считываются из памяти и сохраняются в регистрах R1 и R2 соответственно. В этом случае вычисляется B+1 и результат записывается в R1. Поскольку эта операция включает последовательные чтения и записи и не требует ожидания вызовов функций, переключение или ожидание контекста не происходит. Однако некоторые специальные инструкции требуют системных вызовов, которые подразумевают переключение контекста для ожидания или перевода процессов в спящий режим. Для переключения контекста в режим ядра используется обработчик системных вызовов. Функция display(data x) может потребовать данные x с диска, используя драйвер устройства в режиме ядра. В этом случае функция отображения переходит в спящий режим и ожидает завершения операции READ для получения значения x с диска, что приводит к ожиданию программы и переходу текущей инструкции в спящий режим до тех пор, пока системный вызов не разбудит её. Для поддержания параллелизма программе необходимо повторно выполнить операцию с новым значением и спящим процессом.

Выступление

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

Аппаратное и программное обеспечение

Переключение контекста может выполняться преимущественно программным или аппаратным способом. Некоторые процессоры, такие как Intel 80386 и его последователи, имеют аппаратную поддержку переключения контекста, используя специальный сегмент данных, называемый сегментом состояния задачи (TSS). Переключение задачи может быть инициировано явно инструкцией CALL или JMP, ориентированной на дескриптор TSS в глобальной таблице дескрипторов. Оно может происходить неявно при возникновении прерывания или исключения, если в таблице дескрипторов прерываний (IDT) присутствует шлюз задачи. При переключении задачи процессор может автоматически загрузить новое состояние из TSS. Как и в случае с другими операциями, выполняемыми аппаратно, можно ожидать, что это будет достаточно быстро; однако, основные операционные системы, включая Windows и Linux, не используют эту функцию. Это связано главным образом с двумя причинами: аппаратное переключение контекста не сохраняет все регистры (только регистры общего назначения, а не регистры с плавающей точкой), хотя бит TS автоматически активируется в управляющем регистре CR0, что приводит к ошибке при выполнении инструкций с плавающей точкой и предоставляет ОС возможность сохранять и восстанавливать состояние с плавающей точкой по мере необходимости. Связанные с этим проблемы производительности заключаются в том, что программное переключение контекста может быть выборочным и сохранять только те регистры, которые требуют сохранения, в то время как аппаратное переключение контекста сохраняет почти все регистры, независимо от того, требуются они или нет.