Существует несколько реализаций Python, например, CPython, IronPython, RPython и т. Д.
У некоторых из них есть GIL, у некоторых нет. Например, CPython имеет GIL:
От http://en.wikipedia.org/wiki/Global_Interpreter_Lock
Приложения, написанные на языках программирования с GIL, могут быть спроектированы так, чтобы использовать отдельные процессы для достижения полного параллелизма, поскольку каждый процесс имеет свой собственный интерпретатор и, в свою очередь, имеет свой собственный GIL.
Преимущества GIL
- Увеличена скорость однопоточных программ.
- Простая интеграция библиотек C, которые обычно не являются поточно-ориентированными.
Почему 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 ухудшает вашу производительность (см. Обсуждение выше), вы можете позволить вашему потоку порождать процесс и ждать его завершения.