# Управление режимом потоков ![](Gurkin.jpg) Поток выполнения (thread) представляет собой наименьшую единицу обработки, которой операционная система выделяет процессорное время. В отличие от процессов, потоки одного приложения разделяют адресное пространство и ресурсы, что ускоряет обмен данными, но требует осторожной синхронизации. Ключевая задача планировщика – управление режимами потоков: пользовательским (user mode) и режимом ядра (kernel mode). Переход между ними (переключение контекста) занимает сотни тактов процессора, поэтому частая смена режимов снижает общую производительность системы. ### Основные алгоритмы планирования потоков Современные ОС используют различные дисциплины диспетчеризации, каждая из которых подходит для определённого класса задач. 1. **FCFS (First Come, First Served)** – простейший невытесняющий алгоритм. Потоки выполняются в порядке поступления. Недостаток: «эффект конвоя», когда короткий поток вынужден ждать завершения длинного. Применяется в пакетной обработке. 2. **Round Robin (RR)** – циклическое планирование с квантом времени (обычно 10–100 мс). Каждый поток получает фиксированный отрезок CPU. Обеспечивает низкую задержку отклика для интерактивных приложений. Недостаток: частые переключения контекста. 3. **Приоритетное планирование** – каждому потоку назначается числовой приоритет (чем меньше число, тем выше приоритет). Планировщик всегда выбирает готовый поток с наивысшим приоритетом. Возможно вытеснение (preemptive) и невытесняющее (non-preemptive). Основная проблема – «голодание» низкоприоритетных потоков. Решение – старение приоритетов: со временем приоритет ожидающего потока искусственно повышается. 4. **Многоуровневые очереди с обратной связью** – потоки разделены на классы (фоновые, интерактивные, реального времени). Каждая очередь использует свой алгоритм (например, RR для интерактивных, FCFS для фоновых). Поток может переходить между очередями в зависимости от поведения (использовал весь квант – понижается в очередь). ### Управление режимами: user mode и kernel mode Поток может находиться в двух режимах: - **Пользовательский режим** – доступ к ограниченному набору инструкций и виртуальной памяти. Приложения выполняются именно здесь. - **Режим ядра** – полный доступ к оборудованию и системным структурам. Переход происходит при системных вызовах (read, write, open), обработке прерываний или исключениях (ошибка страницы). Переключение из user mode в kernel mode требует сохранения регистров, переключения таблиц страниц и стека ядра. Этот процесс называется «переключением контекста режима». Современные процессоры поддерживают инструкции syscall/sysret (x86_64) для ускорения перехода. ### Влияние на производительность и многопоточность Частые переключения между режимами увеличивают накладные расходы. Например, если поток делает много коротких системных вызовов (чтение по 1 байту), он будет постоянно переключать режим, снижая эффективность. Оптимизация: группировка вызовов, использование буферов. Гибридные модели потоков (N:M) позволяют управлять режимами на уровне библиотеки пользователя, минимизируя входы в ядро. Пример – библиотека Go (горутины), где планировщик работает в user space. ### Пример настройки параметров ядра Linux В Linux можно влиять на управление потоками через файлы `/proc/sys/kernel/sched_*`: - `sched_min_granularity_ns` – минимальный квант времени. - `sched_wakeup_granularity_ns` – задержка перед вытеснением при пробуждении потока. Команда `chrt` задаёт политику планирования (SCHED_FIFO, SCHED_RR, SCHED_OTHER). ### Заключение Грамотное управление режимами потоков позволяет достичь баланса между отзывчивостью системы и пропускной способностью. Разработчику важно понимать, как планировщик ОС принимает решения, чтобы писать эффективные многопоточные приложения. Выбор алгоритма и настройка параметров должны соответствовать характеру нагрузки: для серверов – высокая пропускная способность, для десктопов – минимальная задержка.