Я сподіваюся, що хтось може дати деяке розуміння того, що принципово відрізняється від віртуальної машини Java, що дозволяє їй добре реалізовувати теми без необхідності блокування глобального інтерпретатора (GIL), тоді як Python потребує такого зла.
Я сподіваюся, що хтось може дати деяке розуміння того, що принципово відрізняється від віртуальної машини Java, що дозволяє їй добре реалізовувати теми без необхідності блокування глобального інтерпретатора (GIL), тоді як Python потребує такого зла.
Відповіді:
Python (мова) не потребує GIL (саме тому він може ідеально реалізовуватися на JVM [Jython] та .NET [IronPython], а ці реалізації безперервно читаються). CPython (популярна реалізація) завжди використовував GIL для зручності кодування (наприклад, кодування механізмів збору сміття) та інтеграції бібліотек, що не захищені потоками C, кодованих С (раніше було багато таких навколо; -).
Проект Unladen Swallow , серед інших амбітних цілей, планує віртуальну машину , що не містить GIL для Python, - цитуючи цей сайт, "Крім того, ми маємо намір видалити GIL і виправити стан багатопотокового прочитання в Python. Ми вважаємо, що це можливо завдяки впровадженню більш досконалої системи GC, на кшталт IBM Recycler (Bacon et al, 2001). "
JVM (принаймні, гаряча точка) має подібну концепцію до "GIL", вона просто набагато тонша за своєю деталізацією замку, більша частина цього походить від GC в точці доступу, яка є більш розвиненою.
У CPython це один великий замок (напевно, не такий правдивий, але досить гарний для аргументів), у JVM він більше розповсюджується з різними поняттями залежно від того, де він використовується.
Погляньте, наприклад, на vm / runtime / safepoint.hpp у коду точки доступу, який фактично є бар'єром. Опинившись у безпечній точці, весь VM зупинився щодо коду Java, подібно до того, як VM пітона зупиняється на GIL.
У світі Java такі події паузи VM відомі як "стоп-світ", у цих точках вільний запуск лише нативного коду, який пов'язаний з певними критеріями, решта VM зупинена.
Крім того, відсутність грубого блокування у Java робить JNI набагато складніше писати, оскільки JVM робить менші гарантії щодо свого оточення для викликів FFI, що є одним із речей, які cpython робить досить простим (хоча не таким простим, як використання ctypes).
Нижче є коментар у цій публікації в блозі http://www.grouplens.org/node/244, яка натякає на причину, чому було так просто відмовитися від GIL для IronPython або Jython, це те, що CPython використовує підрахунок посилань, тоді як в інших 2 ВМ є сміттєзбірники.
Точної механіки, чому це так, я не розумію, але це звучить як правдоподібна причина.
У цьому посиланні вони мають таке пояснення:
... "Частини Інтерпретатора не є безпечними для потоків, хоча здебільшого через те, що зробити їх усіма безпечними нитками при масовому використанні блокування сповільнить надзвичайно однопоточний зв'язок ( джерело ). Це, мабуть, пов'язане зі збирачем сміття CPython, використовуючи підрахунок посилань (JVM і CLR не роблять, і тому не потрібно щоразу блокувати / випускати посилання). Але навіть якщо хтось подумав про прийнятне рішення та реалізував його, у сторонніх бібліотек все одно виникнуть ті самі проблеми ".
У Python не вистачає jit / aot, і тимчасовий проміжок, який він написав на багатопотокових процесорах, не існував. Крім того, ви можете перекомпілювати все в Джулії Янг, у якому не вистачає GIL, і отримати деякий приріст швидкості на вашому Python-коді. Також Jython вид смокче повільніше, ніж Cpython та Java. Якщо ви хочете дотримуватися Python, можете скористатися паралельними плагінами, ви не отримаєте миттєвого підвищення швидкості, але ви можете виконати паралельне програмування з правильним плагіном.