Что такое функция 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 поможет.