Почему в виртуальной машине Java нет GIL? Почему Python нужно так плохо?

Я надеюсь, что кто-то может дать некоторое представление о том, что принципиально отличается от виртуальной машины Java, что позволяет ему красиво внедрять потоки без необходимости использования Global Interpreter Lock (GIL), в то время как Python требует такого зла.

Ответ 1

Python (язык) не нуждается в GIL (поэтому он отлично может быть реализован на JVM [Jython] и .NET [IronPython], и эти реализации многопоточно свободно). CPython (популярная реализация) всегда использовала GIL для упрощения кодирования (особенно для кодирования механизмов сбора мусора) и интеграции не-потокобезопасных C-кодированных библиотек (там было много таких; -.)

Проект Unladen Swallow, среди других амбициозных целей, plan виртуальная машина, не содержащая GIL для Python, - чтобы процитировать этот сайт: "Кроме того, мы намерены удалить GIL и исправить состояние многопоточности в Python. Мы считаем, что это возможно благодаря реализации более сложная система GC, что-то вроде IBM Recycler (Bacon et al, 2001).

Ответ 2

JVM (по крайней мере, "горячая точка" ) имеет аналогичную концепцию "GIL", она намного более тонкая в своей гранулярности блокировки, большая часть этого происходит от GC в горячих точках, которые являются более продвинутыми.

В CPython это один большой замок (возможно, не тот, но верный, но достаточно хорош для аргументов), в JVM он более распространен с различными концепциями в зависимости от того, где он используется.

Взгляните, например, на vm/runtime/safepoint.hpp в код точки доступа, что фактически является барьером. Когда-то в safepoint вся виртуальная машина остановилась относительно java-кода, так же как и виртуальная машина python останавливается в GIL.

В мире Java такие события приостановки VM называются "stop-the-world", в этих точках только собственный код, привязанный к определенным критериям, является свободным запуском, остальная часть VM остановлена.

Также отсутствие грубой блокировки в java делает JNI намного сложнее написать, поскольку JVM делает меньше гарантий относительно своей среды для вызовов FFI, одна из вещей, которые cpython делает довольно легко (хотя и не так просто, как использование ctypes).

Ответ 3

В этом блоге http://www.grouplens.org/node/244, который подсказывает, почему так легко было отказаться от GIL для IronPython или Jython, это то, что CPython использует подсчет ссылок, тогда как у других 2 виртуальных машин есть сборщики мусора.

Точная механика, почему это так, я не получаю, но это звучит как правдоподобная причина.

Ответ 4

В этой ссылка у них есть следующее объяснение:

... "Части интерпретатора не являются потокобезопасными, хотя в основном потому, что их использование в потоковом режиме с помощью массивного использования блокировки будет чрезвычайно медленным однопоточным ( источник). Это, по-видимому, связано с сборщиком мусора CPython с использованием подсчета ссылок (JVM и CLR этого не делают, и поэтому не нужно каждый раз блокировать/освобождать счетчик ссылок). Но даже если кто-то думал о приемлемом решении и реализовал его, у сторонних библиотек все равно были бы те же проблемы".

Ответ 5

Python не хватает jit/aot, и временные рамки, которые были написаны на многопоточных процессорах, не существовали. В качестве альтернативы вы можете перекомпилировать все в Julia lang, в котором отсутствует GIL, и получить некоторый прирост скорости в вашем коде Python. Кроме того, Jython отсасывает его медленнее Cpython и Java. Если вы хотите, чтобы Python рассматривал использование параллельных плагинов, вы не получите мгновенного повышения скорости, но вы можете выполнять параллельное программирование с помощью правого плагина.