Как интерпретирующему языку можно избежать использования Global Interpreter lock (GIL)?
CPython использует глобальную блокировку интерпретатора. Linux удалил все следы Большой блокировки ядра. Какая альтернатива этим замкам? Как система может в полной мере использовать действительно многоядерную или многопроцессорную систему, не останавливая все?
4 ответа
GIL не был бы необходим, если бы Python использовал более продвинутый сборщик мусора, такой как IBM Recycler, основанный на примитивном методе подсчета ссылок. Это то, что Unladen Swallow делает для улучшения производительности Python. Более многообещающим ответом является Stackless Python, который использует собственную реализацию микропотока, а не полагается на операционную систему, подобную традиционному CPython.
GIL зависит от процесса, поэтому вы можете обойти его, запустив несколько процессов Python. Многопроцессорный модуль обеспечивает простой в использовании API для этого.
Другой способ - использовать C-расширения (или написать свои собственные), которые выпускают GIL, выполняя необходимый вам тип обработки данных.
Просто. Не имеют изменяемого состояния, как у Haskell и других функциональных языков программирования. Поскольку ничего в памяти не нужно менять, глобальная блокировка не нужна.
Вы можете избавиться от GIL точно так же, как парни из Linux избавились от Big Kernel Lock: просто добавьте множество более мелкозернистых блокировок или используйте атомарные примитивы, которые не нуждаются в блокировках.
Недостатком и главной причиной, по которой Python этого не делает, является производительность. Например, интерпретатор Tcl не имеет GIL, но может быть скомпилирован как многопоточный, так и не поточный, если вы используете многопоточную версию, вы получите производительность примерно на 10-20% меньше, чем в однопоточном случае. Так что, если вы не используете потоки, это на самом деле медленнее. Были исправления Python для добавления меньших блокировок, но они имели еще худшее влияние на производительность, поэтому были отклонены.
Это просто компромисс, разработчики Python решили, что производительность одного потока (и обратная совместимость с C-расширениями) гораздо важнее, чем возможность использовать много потоков на уровне Python. Вы по-прежнему можете свободно использовать потоки внутри C-расширения, но это не имеет смысла на уровне языка Python.