Ответ
Современные ОС используют механизм вытесняющей многозадачности (preemptive multitasking). Ключевую роль в нём играет планировщик ОС (OS scheduler), который принудительно приостанавливает один поток и запускает другой. Этот процесс называется переключением контекста (context switch).
Переключение происходит по нескольким причинам:
- Истечение кванта времени: Потоку выделяется небольшой промежуток времени (квант) для работы на CPU. Когда он заканчивается, планировщик передает управление другому потоку.
- Блокирующая операция: Поток сам уходит в состояние ожидания, например, при чтении файла с диска или ожидании ответа по сети. В этот момент ОС немедленно переключается на другой готовый к выполнению поток.
- Приоритеты: Поток с более высоким приоритетом может «вытеснить» поток с низким приоритетом.
- Аппаратные прерывания: Внешние события (например, ввод с клавиатуры) вызывают прерывание, в ходе обработки которого планировщик может принять решение о переключении потоков.
Пример на Python, иллюстрирующий вытеснение:
import threading
import time
def worker(name):
print(f"Поток {name}: начал работу.")
# Бесконечный цикл, имитирующий активную работу
# ОС будет принудительно переключаться между потоками
i = 0
while i < 5_000_000:
i += 1
print(f"Поток {name}: завершил работу.")
t1 = threading.Thread(target=worker, name="A")
t2 = threading.Thread(target=worker, name="B")
t1.start()
t2.start()
t1.join()
t2.join()
Даже без time.sleep() или операций ввода-вывода, ОС будет переключать управление между t1 и t2, чтобы обеспечить их параллельное выполнение.
Ответ 18+ 🔞
Так, слушай, про современные операционки. Они же, блядь, работают на вытесняющей многозадачности, понимаешь? Это когда система сама, как мать родная, решает, кому сейчас на процессоре пожить. Главный по тарелочкам тут — планировщик ОС, этакий дирижёр ебаный. Он подходит к потоку, который уже своё отъебашил, и говорит: "Всё, дружок, свободен, следующий на сцену!" Этот цирк и зовётся переключением контекста.
А переключается он, сука, по разным поводам, вот смотри:
- Квант времени кончился. Каждому дали по чуть-чуть — и хватит, не жадничай! Пока другие тоже хотят.
- Поток сам сдался. Пошёл файл читать или сеть ждать — сиди, мудак, жди. А процессор в это время другим делом займётся, не будет простаивать, как дурак.
- Приоритеты, блядь. Важный начальник-поток пришёл — все низкоприоритетные сосунки в сторонку.
- Железо впендюрилось. Клавиатуру нажали или мышь дёрнули — раз! прерывание, и планировщик уже решает, не сменить ли программу.
Вот, смотри, на Python'е как это выглядит, чтоб понятнее было:
import threading
import time
def worker(name):
print(f"Поток {name}: начал работу.")
# Бесконечный цикл, имитирующий активную работу
# ОС будет принудительно переключаться между потоками
i = 0
while i < 5_000_000:
i += 1
print(f"Поток {name}: завершил работу.")
t1 = threading.Thread(target=worker, name="A")
t2 = threading.Thread(target=worker, name="B")
t1.start()
t2.start()
t1.join()
t2.join()
Видишь? Тут даже time.sleep() нет, потоки просто тупо циклы крутят. Но система-то не дура, она их будет тасовать, как карты, чтобы оба впечатление параллельной работы создавали. Чистая магия, ёпта, и немного насилия над процессами.