You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Document subinterpreter modes and Python version requirements
- Document four execution paths: SHARED_GIL (3.12+), OWN_GIL (3.14+),
free-threaded (3.13+), and BEAM processes
- Clarify worker mode is now the default
- Explain why OWN_GIL requires Python 3.14+ (C extension global state bugs)
- Note that SHARED_GIL isolation improves in Python 3.14+
- Update getting-started.md with context mode examples
True parallelism without GIL contention using Python 3.12+ sub-interpreters:
317
+
True parallelism without GIL contention using Python 3.14+ OWN_GIL sub-interpreters:
317
318
318
319
```erlang
319
-
%% Execute multiple calls in parallel across sub-interpreters
320
+
%% Execute multiple calls in parallel across OWN_GIL sub-interpreters
321
+
%% Requires Python 3.14+
320
322
{ok, Results} =py:parallel([
321
323
{math, factorial, [100]},
322
324
{math, factorial, [200]},
@@ -326,6 +328,8 @@ True parallelism without GIL contention using Python 3.12+ sub-interpreters:
326
328
%% Each call runs in its own interpreter with its own GIL
327
329
```
328
330
331
+
For Python 3.12/3.13, use SHARED_GIL sub-interpreters (`mode => subinterp`) for namespace isolation, but note that parallelism is limited by the shared GIL.
332
+
329
333
## Parallel Processing with BEAM Processes
330
334
331
335
Leverage Erlang's lightweight processes for massive parallelism:
@@ -595,19 +599,47 @@ ok = py:clear_traces().
595
599
596
600
## Execution Modes
597
601
598
-
The library auto-detects the best execution mode:
602
+
### Context Modes
599
603
600
-
| Mode | Python Version | Parallelism |
604
+
When creating Python contexts, you can choose the execution mode:
605
+
606
+
| Mode | Python Version | Description |
601
607
|------|----------------|-------------|
602
-
| Free-threaded | 3.13+ (nogil) | True parallel, no GIL |
603
-
| Sub-interpreter | 3.12+ | Per-interpreter GIL |
604
-
| Multi-executor | Any | GIL contention |
608
+
|`worker`| Any | Main interpreter, shared namespace (default, recommended) |
%% With free-threaded Python (3.13t+), provides true parallelism automatically
615
+
{ok, Ctx} =py_context:new(#{}).
616
+
617
+
%% Explicit subinterpreter with shared GIL (Python 3.12+)
618
+
%% Provides namespace isolation but no parallelism
619
+
{ok, Ctx} =py_context:new(#{mode=>subinterp}).
620
+
621
+
%% OWN_GIL mode for true parallelism (Python 3.14+ required)
622
+
%% Each context runs in its own pthread with independent GIL
623
+
{ok, Ctx} =py_context:new(#{mode=>owngil}).
624
+
```
625
+
626
+
**Worker mode is recommended** because it works with any Python version and automatically benefits from free-threaded Python (3.13t+) when available.
627
+
628
+
**Why OWN_GIL requires Python 3.14+**: Some C extensions (e.g., `_decimal`) have global state bugs in sub-interpreters on Python 3.12/3.13. These are fixed in Python 3.14. SHARED_GIL mode works on 3.12+ but with caveats for C extensions with global state.
|`owngil`| 3.14+ | OWN_GIL sub-interpreter, each has own GIL |
288
+
289
+
**Worker mode is recommended** because it works with any Python version and automatically benefits from free-threaded Python (3.13t+) when available.
290
+
291
+
**Why OWN_GIL requires Python 3.14+**: C extensions like `_decimal` have global state bugs in sub-interpreters on Python 3.12/3.13. These are fixed in Python 3.14. SHARED_GIL mode works on 3.12+ but some C extensions may have issues.
Copy file name to clipboardExpand all lines: docs/owngil_internals.md
+11-7Lines changed: 11 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,12 +2,14 @@
2
2
3
3
## Overview
4
4
5
-
OWN_GIL mode provides true parallel Python execution using Python 3.12+ per-interpreter GIL (`PyInterpreterConfig_OWN_GIL`). Each OWN_GIL context runs in a dedicated pthread with its own subinterpreter and GIL.
5
+
OWN_GIL mode provides true parallel Python execution using Python 3.14+ per-interpreter GIL (`PyInterpreterConfig_OWN_GIL`). Each OWN_GIL context runs in a dedicated pthread with its own subinterpreter and GIL.
6
+
7
+
**Note**: OWN_GIL requires Python 3.14+ due to C extension global state bugs in earlier versions (e.g., `_decimal`). For Python 3.12/3.13, use SHARED_GIL sub-interpreters (`mode => subinterp`) which provide namespace isolation but share the GIL.
6
8
7
9
## Quick Start
8
10
9
11
```erlang
10
-
%% Create an OWN_GIL context (requires Python 3.12+)
12
+
%% Create an OWN_GIL context (requires Python 3.14+)
11
13
{ok, Ctx} =py_context:start_link(1, owngil),
12
14
13
15
%% Basic operations work the same as other modes
@@ -79,11 +81,13 @@ All major erlang_python features work with OWN_GIL mode:
79
81
80
82
## Comparison with Other Modes
81
83
82
-
| Mode | Thread Model | GIL | Parallelism |
83
-
|------|-------------|-----|-------------|
84
-
|`worker`| Dirty scheduler | Main interpreter GIL | None |
**Why version requirements differ**: The `subinterp` mode (SHARED_GIL) works on Python 3.12+ for namespace isolation. However, `owngil` mode requires Python 3.14+ because C extensions like `_decimal` have global state that crashes in OWN_GIL sub-interpreters on earlier versions. Python 3.14 includes fixes for these issues (see [cpython#106078](https://github.com/python/cpython/issues/106078)).
0 commit comments