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