Что такое переключение контекста (context switch) в планировщике ОС?

«Что такое переключение контекста (context switch) в планировщике ОС?» — вопрос из категории Linux, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Переключение контекста — это операция ядра ОС, при которой процессор переходит от выполнения одного процесса (или потока) к другому. Для этого ядро должно:

  1. Сохранить контекст текущего исполняемого процесса (значения регистров CPU, указатель на стек, состояние программы — Program Counter).
  2. Загрузить контекст следующего, запланированного к выполнению процесса.
  3. Передать управление загруженному контексту.

С точки зрения DevOps и производительности это критически важно, потому что:

  • Это дорогая операция: Затраты на сохранение/загрузку регистров, обновление таблиц памяти (TLB flush), потенциальные промахи в кэшах процессора. Один контекст-свитч может занимать от микросекунд до миллисекунд.
  • Высокий rate переключений (cswch/s) — ключевой индикатор проблем.
    • Причина: Слишком много активных процессов/потоков (thread thrashing), процессы постоянно блокируются на вводе-выводе (I/O bound).
    • Следствие: Процессор тратит время на администрирование, а не на полезную работу. Падает throughput системы.

Мониторинг и анализ:

# Команда vmstat показывает переключения контекста и прерывания
vmstat 1
# Вывод включает:
# cs (context switches per second) - переключения контекста
# in (interrupts per second) - прерывания

# Более детально с pidstat
pidstat -w 1
# Показывает cswch/s (добровольные) и nvcswch/s (недобровольные) для каждого процесса.

Оптимизация (DevOps-подход):

  • Настройка планировщика задач (CFS): Правильная настройка sched_min_granularity_ns, sched_wakeup_granularity_ns.
  • Использование taskset/cpuset: Привязка CPU-интенсивных процессов к конкретным ядрам, чтобы уменьшить миграцию.
  • Проектирование приложений: Избегать создания чрезмерного количества блокирующихся потоков. Использовать асинхронные модели (например, epoll) для I/O-bound сервисов.