Python GIL, multiprocessing и garbage collection
Что такое GIL в CPython, когда использовать multiprocessing вместо multithreading и как работает garbage collection?
Ответить самому
Сначала сформулируйте ответ как на собеседовании, затем откройте разбор и оцените себя.
Короткий ответ
GIL не дает нескольким threads одновременно исполнять Python bytecode в CPython. Threads полезны для I/O, процессы - для CPU-bound Python. Память в CPython в основном освобождается reference counting, а cyclic GC добирает reference cycles.
Полный разбор
GIL защищает внутреннее состояние CPython interpreter, поэтому несколько Python threads не исполняют Python bytecode параллельно. Это не значит, что threads бесполезны: они хорошо подходят для network/disk/database waits и native extensions, которые release GIL.
Для CPU-bound pure Python задач лучше использовать multiprocessing, vectorized native libraries, compiled extensions или distributed execution. Multiprocessing запускает отдельные interpreter processes с отдельной памятью, поэтому использует несколько cores, но платит serialization, IPC и memory overhead.
CPython освобождает большинство объектов через reference counting: когда счетчик ссылок падает до нуля, объект можно удалить. Отдельно есть cyclic garbage collector для циклов ссылок, которые reference counting сам не разорвет. В других runtime встречаются tracing collectors: mark-and-sweep, generational GC и похожие схемы.
Теория
GIL ограничивает parallel CPU execution в CPython threads; выбор threads/processes зависит от I/O-bound или CPU-bound характера работы.
Типичные ошибки
- Говорить, что Python вообще не умеет concurrency.
- Использовать threads для тяжелого pure Python CPU workload.
- Свести garbage collection только к “переменная больше не нужна”.
Как отвечать на собеседовании
- Сразу разделите I/O-bound и CPU-bound.
- Упомяните reference counting и cyclic GC.