Почему Global Interpreter Lock?

Какова именно функция глобальной блокировки интерпретатора Python? Используют ли другие языки, компилируемые в байт-код, аналогичный механизм?

Вы также должны спросить: "Это вообще имеет значение?"

S.Lott 05.11.2008 23:18

Я согласен, я считаю, что теперь это не проблема, потому что в 2.6 был добавлен модуль многопроцессорности, позволяющий программировать с использованием нескольких процессов потокоподобным образом. docs.python.org/library/multiprocessing.html

monkut 06.11.2008 04:16

Что такое Гил: stackoverflow.com/questions/1294382/…, связанный с программистами: softwareengineering.stackexchange.com/questions/186889/…

Ciro Santilli新疆棉花TRUMP BAN BAD 23.03.2019 10:38
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
89
3
16 668
6

Ответы 6

Следующее взято из официальное справочное руководство по Python / C API:

The Python interpreter is not fully thread safe. In order to support multi-threaded Python programs, there's a global lock that must be held by the current thread before it can safely access Python objects. Without the lock, even the simplest operations could cause problems in a multi-threaded program: for example, when two threads simultaneously increment the reference count of the same object, the reference count could end up being incremented only once instead of twice.

Therefore, the rule exists that only the thread that has acquired the global interpreter lock may operate on Python objects or call Python/C API functions. In order to support multi-threaded Python programs, the interpreter regularly releases and reacquires the lock -- by default, every 100 bytecode instructions (this can be changed with sys.setcheckinterval()). The lock is also released and reacquired around potentially blocking I/O operations like reading or writing a file, so that other threads can run while the thread that requests the I/O is waiting for the I/O operation to complete.

Я думаю, что это довольно хорошо резюмирует проблему.

Я тоже читал, но не могу понять, чем Python в этом отношении отличается, скажем, от java (не так ли?)

Federico A. Ramponi 05.11.2008 19:34

Потоки @EliBendersky Python реализованы как потоки pthread и обрабатываются ОС (dabeaz.com/python/UnderstandingGIL.pdf), тогда как потоки Java - это потоки уровня приложения, планирование которых обрабатывается JVM.

gokul_uf 12.03.2016 10:40

Глобальная блокировка интерпретатора - это большая блокировка типа мьютекса, которая защищает счетчики ссылок от перехвата. Если вы пишете чистый код Python, все это происходит за кулисами, но если вы встраиваете Python в C, вам, возможно, придется явно снять / снять блокировку.

Этот механизм не связан с компиляцией Python в байт-код. Для Java это не нужно. Фактически, это даже не нужно для Jython (python скомпилирован в jvm).

см. также этот вопрос

«Этот механизм не связан с компиляцией Python в байт-код»: точнее, это артефакт реализации CPython. Другие реализации (например, Jython, о котором вы упомянули) могут быть свободны от этого ограничения в силу их поточно-ориентированной реализации.

Eli Bendersky 05.11.2008 19:40

Что касается вашего второго вопроса, не все языки сценариев используют это, но это только делает их менее мощными. Например, потоки в Ruby - это зеленый, а не собственные.

В Python потоки являются собственными, и GIL только предотвращает их запуск на разных ядрах.

В Perl потоки еще хуже. Они просто копируют интерпретатор целиком и далеко не так удобны, как в Python.

В общем, для решения любой проблемы безопасности потоков вам необходимо защитить свои внутренние структуры данных с помощью блокировок. Это можно сделать с различными уровнями детализации.

  • Вы можете использовать мелкозернистую блокировку, когда каждая отдельная структура имеет свою собственную блокировку.

  • Вы можете использовать грубую блокировку, когда одна блокировка защищает все (подход GIL).

У каждого метода есть свои плюсы и минусы. Мелкозернистая блокировка обеспечивает больший параллелизм - два потока могут выполняются параллельно, когда у них нет общих ресурсов. Однако существуют гораздо большие административные издержки. Для для каждой строчки кода может потребоваться получение и снятие нескольких блокировок.

При крупнозернистом подходе все наоборот. Два потока не могут выполняться одновременно, но отдельный поток будет работать быстрее, потому что он не выполняет так много учетных записей. В конечном итоге все сводится к компромиссу между однопоточной скоростью и параллелизмом.

Было предпринято несколько попыток удалить GIL в python, но дополнительные накладные расходы для однопоточных машин, как правило, были слишком большими. Некоторые случаи могут быть медленнее даже на многопроцессорных машинах. из-за конфликта блокировок.

Do other languages that are compiled to bytecode employ a similar mechanism?

Он варьируется, и, вероятно, его не следует рассматривать как свойство языка в большей степени, чем свойство реализации. Например, существуют реализации Python, такие как Jython и IronPython, которые используют поточный подход своей базовой виртуальной машины, а не подход GIL. Кроме того, следующая версия Ruby, похоже, будет перемещать к, вводя GIL.

можете ли вы объяснить это: «Два потока не могут работать одновременно»? Недавно я написал простой веб-сервер на Python с многопоточностью. Для каждого нового запроса от клиента серверы порождают для него новый поток, и этот поток продолжает выполняться. Значит, одновременно будет работать несколько потоков? Или я неправильно понял?

avi 02.12.2013 08:22

@avi AFAIK потоки python не могут работать одновременно, но это не значит, что один поток должен блокировать другой. GIL означает только то, что только один поток может интерпретировать код Python одновременно, это не означает, что управление потоками и распределение ресурсов не работают.

Benproductions1 06.02.2014 12:31

^ поэтому в любой момент времени только один поток будет обслуживать контент для клиента ... поэтому нет смысла использовать многопоточность для повышения производительности. Правильно?

avi 06.02.2014 14:34

И, конечно же, Java скомпилирована в байтовый код и допускает очень мелкозернистую блокировку.

Warren Dew 06.04.2014 13:48

@avi, процесс, связанный с вводом-выводом, такой как веб-сервер, все еще может получать выгоду от потоков Python. Два или более потока могут выполнять ввод-вывод одновременно. Они просто не могут быть интерпретированы (CPU) одновременно.

Saish 15.04.2015 19:11

@avi и все, кто хочет узнать больше о GIL, dabeaz.com/python/UnderstandingGIL.pdf

gokul_uf 12.03.2016 10:36

Python, как и Perl 5, изначально не разрабатывался как потокобезопасный. Потоки были наложены постфактум, поэтому глобальная блокировка интерпретатора используется для поддержания взаимного исключения, когда только один поток выполняет код в данный момент времени в недрах интерпретатора.

Отдельные потоки Python совместно выполняют многозадачность самим интерпретатором, время от времени циклически переключая блокировку.

Самостоятельный захват блокировки необходим, когда вы разговариваете с Python из C, когда другие потоки Python активны, чтобы «подключиться» к этому протоколу и убедиться, что за вашей спиной ничего небезопасного не происходит.

Другие системы, унаследованные от однопоточных, которые позже превратились в многопоточные системы, часто имеют какой-либо механизм такого рода. Например, ядро ​​Linux имеет «большую блокировку ядра» с первых дней SMP. Постепенно, по мере того, как производительность многопоточности становится проблемой, появляется тенденция пытаться разбить такого рода блокировки на более мелкие части или заменить их алгоритмами без блокировок и структурами данных, где это возможно, чтобы максимизировать пропускную способность.

+1 за упоминание того факта, что используется грубая блокировка, чем многие думают, особенно часто забываемый BKL (я использую reiserfs - единственная реальная причина, по которой я вообще знаю об этом).

new123456 07.07.2011 05:17

В Linux был BKL, начиная с версии 2.6.39, BKL был полностью удален.

avi 02.12.2013 12:35

Конечно. Имейте в виду, что это было примерно через 3 года после того, как я ответил на вопрос. знак равно

Edward KMETT 08.12.2013 16:43

Возможно, вам поможет статья это от BDFL.

Другие вопросы по теме