Почему глобальный переводчик?

Что такое функция Python Global Interpreter Lock? У других языков, скомпилированных для байт-кода, используется аналогичный механизм?

Ответ 1

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

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

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

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

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

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

У других языков, скомпилированных для байт-кода, используется аналогичный механизм?

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

Ответ 2

Ниже приведено официальное справочное руководство по API Python/C API :

Переводчик Python не полностью безопасный поток. Для поддержки многопоточные программы Python, существует глобальная блокировка, которая должна быть удерживаемый текущей нитью перед ней может безопасно обращаться к объектам Python. Без блокировки даже самые простые операции могут вызвать проблемы в многопоточная программа: например, когда два потока одновременно увеличить счетчик ссылок тот же объект, счетчик ссылок мог бы в конечном итоге увеличивается только один раз а не дважды.

Следовательно, существует правило, что поток, который приобрел блокировка глобального интерпретатора может работать Объекты Python или вызов API Python/C функции. Для поддержки многопоточные программы Python, переводчик регулярно выпускает и reacquires lock - по умолчанию, каждые 100 байткодов (это можно изменить с помощью sys.setcheckinterval()). Блокировка также выпущен и повторно потенциально блокирующие операции ввода-вывода например, чтение или запись файла, поэтому что другие потоки могут поток, который запрашивает ввод-вывод ожидая операции ввода-вывода полная.

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

Ответ 3

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

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

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

Ответ 4

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

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

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

Другие системы, имеющие однопоточное наследие, которые впоследствии эволюционировали в многолистные системы, часто имеют некоторый механизм такого рода. Например, у ядра Linux есть "Big Kernel Lock" с ранних дней SMP. Постепенно с течением времени, когда проблема многопоточности становится проблемой, существует тенденция пытаться разбить эти виды блокировок на более мелкие части или заменить их алгоритмами блокировки и структурами данных, где это возможно, чтобы увеличить пропускную способность.

Ответ 5

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

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

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

Ответ 6

Может быть эта статья BDFL поможет.