Почему синхронный код неэффективно использует CPU при I/O операциях

«Почему синхронный код неэффективно использует CPU при I/O операциях» — вопрос из категории Операционные системы, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В синхронной модели выполнения код исполняется строго последовательно. Основная проблема возникает при выполнении операций ввода-вывода (I/O), таких как чтение файла, сетевой запрос или обращение к базе данных.

Ключевая причина неэффективности — блокировка потока.

Когда поток выполнения доходит до I/O-операции, он блокируется и переходит в состояние ожидания до ее завершения. В это время CPU простаивает (CPU is idle), так как операционная система ждет ответа от внешнего устройства (диска, сети), а поток не может выполнять другие задачи.

Пример на Python:

import time
import requests

def fetch_data_sync():
    print("Отправка запроса...")
    # Поток блокируется здесь, CPU ждет ответа от сервера
    response = requests.get("https://example.com") 
    print("Ответ получен.")
    # Здесь CPU снова работает, обрабатывая ответ
    print(f"Статус: {response.status_code}")

fetch_data_sync()

Последствия:

  1. Низкая утилизация CPU: Процессор не выполняет полезную работу значительную часть времени, что критично для высоконагруженных систем.
  2. Плохая масштабируемость: Для обработки нескольких одновременных запросов требуется создавать отдельные потоки или процессы, что потребляет много памяти и ресурсов ОС.
  3. Увеличение задержки (latency): Общее время выполнения складывается из последовательного ожидания всех блокирующих операций.

Для решения этой проблемы в I/O-bound задачах применяют асинхронное программирование или многопоточность, которые позволяют CPU переключаться на другие задачи, пока одна из них ожидает завершения ввода-вывода.