Я надеюсь, что кто-то сможет дать некоторое представление о том, что принципиально отличается от виртуальной машины Java, которая позволяет ей красиво реализовывать потоки без необходимости глобальной блокировки интерпретатора (GIL), в то время как Python требует такого зла.
Почему в виртуальной машине Java нет GIL? Почему он так нужен Python?
Ответы (5)
Python (язык) не нуждается в GIL (поэтому он может быть отлично реализован на JVM [Jython] и .NET [IronPython], и эти реализации могут свободно работать в многопоточном режиме). CPython (популярная реализация) всегда использовал GIL для простоты кодирования (особенно для кодирования механизмов сборки мусора) и интеграции небезопасных для потоков библиотек, написанных на C (раньше их было множество; -).
Проект Unladen Swallow, среди других амбициозных целей, выполняет спланировать виртуальную машину без GIL для Python - цитируя этот сайт:" Кроме того, мы намерены удалить GIL и исправить состояние многопоточности в Python. Мы считаем, что это возможно за счет реализации более сложной системы сборки мусора, вроде IBM Recycler (Bacon et al, 2001) ».
JVM (по крайней мере, точка доступа) имеет аналогичную концепцию с "GIL", просто она намного более тонкая по степени детализации блокировки, большая часть этого исходит от более продвинутых GC в точке доступа.
В CPython это одна большая блокировка (вероятно, не совсем так, но достаточно для аргументов), в JVM она более распространена с различными концепциями в зависимости от того, где она используется.
Взгляните, например, на vm / runtime / safepoint.hpp в коде точки доступа, который фактически является препятствием. Оказавшись в безопасной точке, вся виртуальная машина остановилась в отношении кода Java, так же как виртуальная машина python останавливается в GIL.
В мире Java такие события приостановки виртуальной машины известны как «остановка мира», в этих точках свободно работает только собственный код, привязанный к определенным критериям, остальная часть виртуальной машины остановлена.
Кроме того, отсутствие грубой блокировки в java делает JNI намного более сложным для написания, поскольку JVM дает меньше гарантий относительно своей среды для вызовов FFI, что является одной из вещей, которые cpython делает довольно легко (хотя и не так просто, как использование ctypes).
Ниже в этом сообщении блога есть комментарий http://www.grouplens.org/node/244, который намекает на причину, по которой было так легко обойтись без GIL для IronPython или Jython, это то, что CPython использует подсчет ссылок, тогда как другие 2 виртуальные машины имеют сборщики мусора.
Я не понимаю точной причины, почему это так, но это действительно похоже на правдоподобную причину.
По этой ссылке У них есть такое объяснение:
... "Части интерпретатора не являются потокобезопасными, хотя в основном потому, что создание их всех потоковообезопасных за счет использования массивных блокировок сильно замедлит однопоточность (source). Похоже, это связано со сборщиком мусора CPython, использующим подсчет ссылок (JVM и CLR нет, и, следовательно, не нужно каждый раз блокировать / освобождать счетчик ссылок). Но даже если бы кто-то придумал приемлемое решение и реализовал его, у сторонних библиотек все равно были бы те же проблемы ».
В Python отсутствует jit / aot, и временных рамок, в которые он был написан на многопоточных процессорах, не существовало. В качестве альтернативы вы можете перекомпилировать все на языке Julia lang, в котором отсутствует GIL, и получить некоторый прирост скорости вашего кода Python. Также Jython отстой, он медленнее, чем Cpython и Java. Если вы хотите придерживаться Python, подумайте об использовании параллельных плагинов, вы не получите мгновенного прироста скорости, но вы можете выполнять параллельное программирование с помощью правильного плагина.