Что такое ядро?
— это основная часть операционной системы. Оно управляет аппаратным обеспечением и системными ресурсами.
Роль ядра: Ядро координирует доступ к процессору, памяти и другим устройствам.
Что такое процесс?
— это программа в состоянии выполнения. Каждый процесс в Linux представляет собой экземпляр программы, запущенной пользователем или системой. Он включает:
Что такое поток?
— это «легковесный процесс», который выполняется в рамках процесса. Потоки:
Что такое CPU-bound и I/O-bound операции?
–CPU-bound задачи: интенсивно используют процессор. Пример – вычисление факториала большого числа.
– I/O-bound задачи: больше зависят от операций ввода-вывода. Пример – загрузка данных с веб-сайта.
Что такое Global Interpreter Lock (GIL) в Python и как он влияет на многопоточность? Какие последствия могут возникнуть при использовании многопоточности в Python из-за GIL?
Это механизм в интерпретаторе CPython, который ограничивает выполнение Python-кода в один поток за раз, даже если в программе используется многопоточность. Это нужно для упрощения управления памятью, но из-за GIL многопоточные Python программы не могут эффективно использовать преимущества многоядерных процессоров для вычислительных задач.
**Последствия:** - В многопоточных Python программах CPU-bound задачи могут страдать от пониженной производительности из-за GIL - IO-bound задачи меньше страдают от GIL, так как операции ввода-вывода могут блокировать поток, освобождая GIL и позволяя другим потокам работатьЭто механизм в интерпретаторе CPython, который ограничивает выполнение Python-кода в один поток за раз, даже если в программе используется многопоточность
Что такое многопоточность и какие преимущества она может предоставить при разработке программного обеспечения?
Это вариант реализации вычислений, при котором выполнение некоторой прикладной задачи запускается и выполняется в нескольких потоках.
**Преимущества:** - Удобство использования для I/O-интенсивных задач и параллельной обработки - Отзывчивость приложений при обработке событий, таких как пользовательский ввод или сетевые запросы - Более низкие затраты на создание и управление потоками по сравнению с процессами
Что такое асинхронное программирование и какие преимущества оно может предоставить при разработке программного обеспечения?
Это модель конкурентного выполнения, позволяющая программе обрабатывать несколько задач одновременно в одном потоке, не блокируя выполнение при ожидании длительных операций.
**Преимущества:** - Высокая производительность I/O-bound задач - Эффективное использование ресурсов - Отзывчивость интерфейса/сервиса - Масштабируемость
В чем разница между многопоточностью и асинхронностью? Какой подход лучше использовать в каких ситуациях?
Многопоточность использует несколько потоков ОС для параллельного выполнения задач в одном процессе, обходя блокировки ввода, вывода (I/O-bound).
Асинхронность работает в одном потоке, переключаясь между задачами во время ожидания.
Основные различия:
Как создать поток в Python? Какие способы существуют для создания потоков?
Потоки (threads) в Python создаются с помощью стандартного модуля threading, предназначенного для параллельного выполнения задач, связынных с вводом-выводом. Основные способы включают передачу целевой функции в конструктор threading.Thread(target=...) или создание подкласса от Thread с переопределением метода run(). Запуск потока осуществляется методом .start(), а ожидание его завершения – .join().
```python
def my_function():
print(“Поток работает”)
time.sleep(1)
Создание потока
thread = threading.Thread(target=my_function)
Запуск потока
thread.start()
Ожидание завершения потока
thread.join()
print(“Поток завершен”)
~~~
Какие модули Python вы знаете для работы с многопоточностью?
Встроенные модули
- `threading`Основной высокоуровневый модуль для создания и управления потоками - `concurrent.futures` Выскоуровневый интерфейс для асинхронного выполнения вызовов - `queue` Модуль для создания безопасных потоковых очередей (FIFO). Используется для обмена данными между потоками, чтобы избежать состояния гонки - `_thread` Низкоуровневый модуль. В основном используется `threading`, так как он удобнее и безопаснее
Какие модули Python вы знаете для работы с асинхронностью?
Основные модули и библиотеки, разделенные по назначению
asyncio Основной модуль в стандартной библиотеке Python для написания однопоточного конкурентного кода с использованием async/awaitconcurrent.futures Высокоуровневый интерфейс для асинхронного выполнения вызываемых объектовaiohttp Самая популярная библиотека для создания асинхронных HTTP-клиентов и серверовhttpx Современный клиент, который поддерживает как синхронный, так и асинхронный режимы, совместимый с API requestswebsockets Библиотека для работы с WebSocket-соединениямиFastAPI. Высокопроизводительный фреймворк для создания APIStarlette Легковесный ASGI-фреймворк, идеальный для высокопроизводительных сервисовSanic Фреймворк, ориентированный на высокую скорость работыQuart Микрофреймворк, совместимый с API Flask, но работающий асинхронноasyncpgmotoraiomysql / aiopgGINOBeanietrioanyiogeventuvloopЧто такое event loop (цикл событий) в асинхронном программировании? Как он работает в Python?
Это реализация паттерна Реактор в асинхронном программировании, которая позволяет системе обрабатывать большое количество задач без создания множества потоков
Основные шаги работы event loop: 1. Ожидание событий. Цикл событий ожидает появления новых задач 2. Помещение задачи в очередь. Когда событие происходит, оно добавляется в очередь задач, ожидающих обработки 3. Выполнение задачи. Цикл событий начинает обработку задачи, извлекая ее из очереди и вызывая соответствующий обработчик 4. Завершение задачи. Когда задача завершена, цикл переходит к следующему событию в очереди
Какие проблемы могут возникнуть при использовании асинхронности? Как их можно решить?
async def функции блокирует весь поток выполненияwaitawaitasyncio не поможет, а лишь добавит накладные расходыasyncio.gather() вызывает исключение, другие задачи могут остаться висеть, а само исключение может “проглотиться” и не быть замеченнымasyncio.create_task(), но не дождались завершения (await), из-за чего могут зависнуть при выходе из программыGIL’s problem. Если lock - это mutex, то почему же возможен результат отличный от 0?
GIL гарантирует, что в один момент времени исполняется только один байткод Python, но он не делает операции над данными атомарными.
Mutex (lock) защищает только тот участок кода, который обернут. Если критическая секция выбрана неправильно, используется несколько локов или часть операций выполняется без блокировки, возможны race condition и результат, отличный от ожидаемого.
При использовании TaskGroup в случае исключения другие задачи могут быть отменены или автоматически отменяются?
Да, Если любая задача внутри TaskGroup выбрасывает исключение, TaskGroup автоматически отменяет все остальные еще не завершенные задачи.
Какие способы синхронизации потоков вы знаете в Python?
Почему свитчинг контекста между потоками дороже чем между корутинами? User space и kernel space?
Переключение контекста между потоками операционной системы дороже, чем между корутинами, в основном из-за того, что потоки управляются ядром, а корутины – приложением. Переключение потоков требует участия операционной системы, в то время как корутины переключаются внутри самого процесса
User Space (Пользовательское пространство): Это непривилегированный режим работы процессора (Ring 3 в архитектуре x86). Программы здесь имеют доступ только к своей виртуальной памяти и не могут напрямую управлять железом.
Kernel Space (Пространство ядра): Это привилегированный режим работы (Ring 0). Здесь работает ядро ОС, имеющее полный контроль над памятью, прерываниями и периферией.
Context Switch (Переключение контекста): Процесс сохранения состояния (регистров, стека) одной задачи и восстановления состояния другой.
Mode Switch (Переключение режима): Переход процессора из Ring 3 в Ring 0 (и обратно) через системный вызов или прерывание.
Manager vs Lock (multiprocessing)
Manager предоставляют доступ к разделителям, объектам и ресурсам, таким как разделяемые списки, словари и прокси-объекты. Это позволяет разным процессам взаимодействовать с общими данными. Один из наиболее частых вариантов использования менеджера – работа с разделяемыми контейнерами данных, такими как разделяемые списки или словари.
Lock используются для обеспечения синхронизации доступа к разделяемым ресурсам между несколькими процессами. Они позволяют предотвратить гонки данных и обеспечить правильный и согласованный доступ к разделяемым ресурсам.
В реальных задачах Manager часто используют вместе с Lock, а для высоконагруженных сценариев выбирают shared memory или Value / Array
Основные варианты создания фоновых задач:
Фоновые задачи в Python можно реализовывать через потоки, процессы, asyncio, executors, а для надежных и долгих задач – через очереди задач вроде Celery. Выбор зависит от того, IO или CPU-bound задача, и нужны ли ретраи и масштабирование
Основные причины существования GIL
Упрощение управления памятью:
- CPython использует подсчет ссылок для управления памятью. Подсчет ссылок требует атомарного изменения счетчика ссылок при создании и удалении ссылок на объект. Без GIL было бы сложно обеспечить атомарность операций изменения счетчика ссылок, особенно в многопоточном окружении.
- GIL упрощает код управления памятью, делая его менее подверженным ошибкам и более простым в реализации.
Поддержание интерпретатора Python:
- GIL упрощает интерпретатор Python, так как многие внутренние структуры данных CPython могут быть не потокобезопасными. Это позволяет разработчикам Python сосредоточиться на производительности и функциональности самого языка, не тратя ресурсы на сложные механизмы синхронизации.
Предотвращение гонок данных:
- Python является динамически типизированным языком, и объекты могут менять свой тип и состояние во время выполнения программы. Без GIL множество потоков могло бы одновременно изменять и обращаться к общим объектам, что могло бы привести к гонкам данных и непредсказуемому поведению программы.
Последствия и ограничения GIL
Многопоточность и производительность:
- В многопоточных Python программах CPU-bound задачи (которые интенсивно используют процессор) могут страдать от пониженной производительности из-за GIL. В таких программах только один поток может исполняться в любой момент времени, что ограничивает параллельное выполнение на многоядерных системах.
Альтернативы и обходные пути:
- Для задач, требующих высокой производительности и параллельного выполнения, можно использовать мультипроцессинг вместо многопоточности. Модуль multiprocessing создает отдельные процессы, каждый из которых имеет свой собственный GIL, что позволяет эффективно использовать многоядерные системы.
Плюсы и минусы GIL
Преимущества GIL в Python:
Недостатки GIL в Python:
Что такое многопоточность?
Это вариант реализации вычислений, при котором выполнение некоторой прикладной задачи запускается и выполняется в нескольких потоках.