Глобальная блокировка интерпретатора (GIL), по-видимому, часто упоминается в качестве основной причины, по которой многопоточность и тому подобное является сложной задачей в Python - что поднимает вопрос «Почему это было сделано в первую очередь?»
Будучи не программистом, я не имею ни малейшего понятия, почему это может быть - какая логика была в том, чтобы вставить GIL?
python
multithreading
фомиты
источник
источник
Ответы:
Существует несколько реализаций Python, например, CPython, IronPython, RPython и т. Д.
У некоторых из них есть GIL, у некоторых нет. Например, CPython имеет GIL:
От http://en.wikipedia.org/wiki/Global_Interpreter_Lock
Приложения, написанные на языках программирования с GIL, могут быть спроектированы так, чтобы использовать отдельные процессы для достижения полного параллелизма, поскольку каждый процесс имеет свой собственный интерпретатор и, в свою очередь, имеет свой собственный GIL.
Преимущества GIL
Почему Python (CPython и другие) использует GIL
В CPython глобальная блокировка интерпретатора, или GIL, является мьютексом, который не позволяет нескольким собственным потокам одновременно выполнять байт-коды Python. Эта блокировка необходима главным образом потому, что управление памятью в CPython не является поточно-ориентированным.
GIL является спорным, поскольку не позволяет многопоточным программам CPython полностью использовать преимущества многопроцессорных систем в определенных ситуациях. Обратите внимание, что потенциально блокирующие или длительные операции, такие как ввод-вывод, обработка изображений и сокращение числа NumPy, происходят вне GIL. Поэтому только в многопоточных программах, которые проводят много времени внутри GIL, интерпретируя байт-код CPython, GIL становится узким местом.
В Python есть GIL, а не мелкозернистая блокировка по нескольким причинам:
Это быстрее в однопоточном корпусе.
Это быстрее в многопоточном случае для программ, связанных с вводом / выводом.
Это быстрее в многопоточном случае для связанных с процессором программ, которые выполняют свою вычислительную работу в библиотеках Си.
Это облегчает написание расширений C: переключение потоков Python не произойдет, кроме случаев, когда вы позволите этому произойти (т. Е. Между макросами Py_BEGIN_ALLOW_THREADS и Py_END_ALLOW_THREADS).
Это делает упаковку библиотек C проще. Вам не нужно беспокоиться о безопасности потоков. Если библиотека не является поточно-ориентированной, вы просто держите GIL заблокированным во время вызова.
GIL может быть выпущен расширениями C. Стандартная библиотека Python выпускает GIL вокруг каждого блокирующего вызова ввода / вывода. Таким образом, GIL не влияет на производительность серверов, связанных с вводом / выводом. Таким образом, вы можете создавать сетевые серверы в Python, используя процессы (fork), потоки или асинхронный ввод-вывод, и GIL не будет вам мешать.
Числовые библиотеки в C или Fortran могут также вызываться с выпущенным GIL. Пока ваше расширение C ожидает завершения FFT, интерпретатор будет выполнять другие потоки Python. Таким образом, GIL легче и быстрее, чем мелкозернистая блокировка в этом случае. Это составляет основную часть численной работы. Расширение NumPy выпускает GIL, когда это возможно.
Потоки обычно являются плохим способом написания большинства серверных программ. Если нагрузка низкая, разветвление легче. Если нагрузка высока, лучше использовать асинхронный ввод-вывод и программирование на основе событий (например, с использованием Twisted Framework Python). Единственным оправданием использования потоков является отсутствие os.fork в Windows.
GIL является проблемой, если и только если вы выполняете работу с интенсивным использованием процессора на чистом Python. Здесь вы можете получить более чистый дизайн, используя процессы и передачу сообщений (например, mpi4py). В магазине сыра Python также есть модуль обработки, который предоставляет процессам тот же интерфейс, что и потоки (т. Е. Заменяет многопоточность. Нить с обработкой. Процесс).
Потоки могут использоваться для поддержки отзывчивости графического интерфейса независимо от GIL. Если GIL ухудшает вашу производительность (см. Обсуждение выше), вы можете позволить вашему потоку порождать процесс и ждать его завершения.
источник
s/RPython/PyPy/g
, @MichaelBorgwardt Приводить доводы в пользу GIL - это своего рода вопрос, не так ли? Хотя я бы согласился, что некоторые из содержания этого ответа (а именно обсуждение альтернатив) не имеет смысла. И к лучшему или к худшему, от пересчета теперь почти невозможно избавиться - он глубоко укоренился во всем API и кодовой базе; почти невозможно избавиться от этого, не переписывая половину кода и не нарушая весь внешний код.multiprocessing
библиотека - стандартная с 2.6. Его рабочие пулы представляют собой супер гладкую абстракцию для некоторых простых типов параллелизма.Прежде всего: Python не имеет GIL. Python - это язык программирования. Язык программирования представляет собой набор абстрактных математических правил и ограничений. В Спецификации языка Python ничего не говорится о том, что должен быть GIL.
Существует много разных реализаций Python. У некоторых есть GIL, у некоторых нет.
Одно простое объяснение наличия GIL заключается в том, что писать параллельный код сложно. Размещая гигантский замок вокруг вашего кода, вы заставляете его всегда работать последовательно. Задача решена!
В частности, в CPython одна важная цель - облегчить расширение интерпретатора с помощью плагинов, написанных на C. Опять же, писать параллельный код сложно, поэтому, гарантируя, что параллелизма не будет, проще будет писать расширения для переводчик. Кроме того, многие из этих расширений являются лишь тонкими обертками вокруг существующих библиотек, которые, возможно, не были написаны с учетом параллелизма.
источник
Какова цель GIL?
Документация CAPI имеет следующее:
Другими словами, GIL предотвращает коррупцию государства. Программы Python никогда не должны вызывать ошибки сегментации, потому что разрешены только безопасные операции с памятью. GIL распространяет эту гарантию на многопоточные программы.
Какие есть альтернативы?
Если целью GIL является защита государства от коррупции, то очевидной альтернативой является блокировка гораздо более тонкого зерна; возможно на уровне объекта. Проблема заключается в том, что, хотя было продемонстрировано, что оно повышает производительность многопоточных программ, в результате возникают дополнительные издержки, и в результате страдают однопоточные программы.
источник