Sam Gross:
Py_mod_gil slot
In --disable-gil
builds, when loading an extension, CPython checks for a new PEP 489-style Py_mod_gil
slot. If the slot is set to Py_mod_gil_not_used
, then extension loading proceeds as normal. If the slot is not set, the interpreter pauses all threads and enables the GIL before continuing. Additionally, the interpreter issues a visible warning naming the extension, that the GIL was enabled (and why) and the steps the user can take to override it.
How will you take out the GIL when you call into the extension?
Its not just the loading of the extension that will have potential race conditions.
Each method call of the extension would need a GIL equilivant I would think.
colesbury
(Sam Gross)
February 1, 2023, 5:52pm
109
To be clear, I am suggesting that the GIL is enabled from that point forward and remains enabled after the extension loading process is completed.
4 Likes
davidhewitt
(David Hewitt)
February 3, 2023, 8:36am
110
This solution would work very well for PyO3 - we would be able to default to requiring GIL and then extension authors can opt out of the GIL when they are comfortable.
I fear that the downside of this approach is that nogil
would take a long time to build traction, because it becomes a problem of extensions being built for it plus extensions being upgraded for it. Nevertheless it’s probably worth it for the safety advantages - a slow and stable rollout would be good from perception of users.
3 Likes
smontanaro
(Skip Montanaro)
February 3, 2023, 3:02pm
111
I’ve been thinking the transition to a GIL-free world would look a lot like the 2-to-3 transition, dragging out interminably. The details would obviously be much different, but giving extension authors an escape hatch would likely delay the widespread adoption of nogil
. Would an application writer know that their presumed GIL-free application had been hamstrung by some extension they might well have no control over? Would they be able to pinpoint the source?
ajoino
(Jacob Nilsson)
February 3, 2023, 3:20pm
113
This is assuming a GIL-free world is the end goal, which, as long as the GIL-ful version is considerably faster in many common Python applications, is a notion I disagree with. Being able to choose between GIL-ful and GIL-free at run-time feels like a better end goal to me but I’m sure there are many reason why that is bad/hard/impractical.
smontanaro
(Skip Montanaro)
February 3, 2023, 6:17pm
114
Barry Scott:
Yes, explained above.
Thanks. The thread has gotten kinda long. I’m only about halfway through the PEP itself and didn’t recall seeing it there.
stonebig
(Stonebig)
February 12, 2023, 2:01pm
115
In preventive case nogil doesn’t make it for 3.12, wouldn’t a convention be already nice on how wheels for this alternate reality shall be named ? … replacing the “c” of “cp” per a “n” for nogil cpython ?
cramjam-2.6.2-cp312-none-win_amd64.whl = with gil
cramjam-2.6.2-np312-none-win_amd64.whl = nogil
cramjam-2.6.2-cp312.np312-none-win_amd64.whl = with or without you nogil
It would allow to use existing pypi infrastructure.
1 Like
brettcannon
(Brett Cannon)
February 23, 2023, 11:13pm
116
There’s no chance of it making it in for 3.12. Not only has this PEP not been sent to the SC yet to even consider accepting it, there isn’t a working 3.12 patch to even begin reviewing (GitHub - colesbury/nogil: Multithreaded Python without the GIL is 8824 commits behind main
as it is).
No because I don’t even necessarily agree it’s an interpreter-level tag difference compared to an ABI tag difference. And I personally don’t want to expound the energy on that debate unless it’s going to be useful (and my active COVID recovery says it wouldn’t be at this time).
1 Like
gunungpw
(Gunung P. Wibisono)
February 24, 2023, 12:36am
117
6 Likes
stonebig
(Stonebig)
February 25, 2023, 9:07am
118
it looks about 80 commits still to apply in the todo of nogil-3.12 , plus about 420 commits from cpython-3.12a4 to now, so nogil-3.12 is roughly 500 commits behind.
Given the benefit it brings to some workloads in the cloud, I would expect that unofficial nogil-3.12 will get a bigger community than pypy, and offering them a pypi way-of-blooming, aside of any SC approval for “mainline cpython”, would be great.
3 Likes
I really like this nogil implementation.
Hope it will be in 3.12 as long as progress on GitHub - colesbury/nogil-3.12: Multithreaded Python without the GIL (experimental rebase on 3.12) continuous
This PR open to Python a new world of “fast” execution and it wouldn’t be needed to place slow code in C++ library
4 Likes
Hi all,
a new discussion has been made, and it seems relevant to notify people who are in this discussion too: PEP 703: Making the Global Interpreter Lock Optional (3.12 updates)
3 Likes
seibert
(Stan Seibert)
July 19, 2023, 6:04pm
121
Hi all,
(I’m not sure where PEP 703 discussion is happening now that several of the major threads here have been locked by the moderators, so apologies if I should post this somewhere else.)
We at Anaconda have been watching the nogil work with great interest for some time. After some internal discussion, I wanted to announce that we are able to commit Anaconda engineer time toward the packaging challenges that will be associated with adopting PEP 703, including any work on pip, cibuildwheel, and conda-forge that will be needed to get nogil-compatible packages into the hands of the Python community. We can coordinate with the PyPA folks to see where we can be most useful if the PEP moves forward.
67 Likes
jrincayc
(Joshua Cogliati)
August 4, 2023, 2:27am
122
FYI: The steering committee decided that “We intend to accept PEP 703, although we’re still working on the acceptance details.”
4 Likes
hugovk
(Hugo van Kemenade)
October 25, 2023, 6:22am
123
The steering council has now formally accepted PEP 703:
(Posted for the whole Steering Council.)
As we’ve announced before , the Steering Council has decided to accept PEP 703 (Making the Global Interpreter Lock Optional in CPython) . We want to make it clear why, and under what expectations we’re doing so.
It is clear to the Steering Council that theoretically, a no-GIL (or free-threaded) Python would be of great benefit, and the majority of the community seems in agreement. Threads have significant downsides and caveats, but they are widely adopte…
12 Likes
jrincayc
(Joshua Cogliati)
October 30, 2023, 2:00am
124
4 Likes
smontanaro
(Skip Montanaro)
November 22, 2023, 12:25pm
125
Has the no-gil code been fully merged to main at this point or is there more to do? I’ve tried configuring with and without --disable-gil
and was mildly surprised not to see a change in the number of test cases run. I would have expected to see some new test cases.
ambv
(Łukasz Langa)
November 22, 2023, 12:27pm
126
It’s work in progress.
Follow this issue for the current state:
opened 03:59PM - 21 Aug 23 UTC
type-feature
interpreter-core
3.13
topic-free-threaded
# Feature or enhancement
The steering council has [accepted](https://discuss.… python.org/t/pep-703-making-the-global-interpreter-lock-optional-in-cpython-acceptance/37075) [PEP 703](https://peps.python.org/pep-0703/). This is intended as a top-level issue to keep track of integration status.
The "up for grabs" list contains issues that no one is currently working on and are ready to be implemented. If you are interested in working on one of them, please comment on the specific issue and CC me (@colesbury) on related PRs.
```[tasklist]
### Up For Grabs (comment on specific issue to take)
- [ ] https://github.com/python/cpython/issues/112205
```
```[tasklist]
### Linked issues
- [ ] https://github.com/python/cpython/issues/108223
- [ ] https://github.com/python/cpython/issues/108374
- [ ] https://github.com/python/cpython/issues/108337
- [ ] https://github.com/python/cpython/issues/108724
- [ ] https://github.com/python/cpython/issues/109549
- [ ] https://github.com/python/cpython/issues/109740
- [ ] https://github.com/python/cpython/issues/110119
- [ ] https://github.com/pypa/packaging/issues/727
- [ ] https://github.com/python/cpython/issues/111062
- [ ] https://github.com/python/cpython/issues/111569
- [ ] https://github.com/python/cpython/issues/112062
- [ ] https://github.com/python/cpython/issues/111903
- [ ] https://github.com/python/cpython/issues/111916
- [ ] https://github.com/python/cpython/issues/111928
- [ ] https://github.com/python/cpython/issues/112070
- [ ] https://github.com/python/cpython/issues/111956
- [ ] https://github.com/python/cpython/issues/110481
- [ ] https://github.com/python/cpython/issues/111506
- [ ] https://github.com/python/cpython/issues/111650
- [ ] https://github.com/python/cpython/issues/111870
- [ ] https://github.com/python/cpython/issues/111924
- [ ] https://github.com/python/cpython/issues/111926
- [ ] https://github.com/python/cpython/issues/111962
- [ ] https://github.com/python/cpython/issues/111964
- [ ] https://github.com/python/cpython/issues/111968
- [ ] https://github.com/python/cpython/issues/111971
- [ ] https://github.com/python/cpython/issues/111972
- [ ] https://github.com/python/cpython/issues/112050
- [ ] https://github.com/python/cpython/issues/112066
- [ ] https://github.com/python/cpython/issues/112075
- [ ] https://github.com/python/cpython/issues/112087
- [ ] https://github.com/python/cpython/issues/112071
- [ ] https://github.com/python/cpython/issues/112069
- [ ] https://github.com/python/cpython/issues/111965
- [ ] https://github.com/python/cpython/issues/112213
```
### Linked PRs
```[tasklist]
### Deferred tasks
- [ ] Revisit and update [`--disable-gil`](https://docs.python.org/dev/using/configure.html#cmdoption-disable-gil) configure documentation
- [ ] Reenable test_cppext on `--disable-gil` builds
```
### Upstream functionality from nogil-3.12
This is a list of commits from the nogil-3.12 PR plan. The crossed-out entries are commits that do not need to be upstreamed, usually because the functionality is already in the main branch.
- [ ] [`cefe5dfee9`](https://github.com/colesbury/nogil-3.12/commit/cefe5dfee9) configure: disallow "--with-trace-refs" for "--disable-gil" builds
- [ ] [`dcddbe2ddb`](https://github.com/colesbury/nogil-3.12/commit/dcddbe2ddb) configure: add support for --with-thread-sanitizer
- [ ] [`f546dbf16a`](https://github.com/colesbury/nogil-3.12/commit/f546dbf16a) Enable/disable the GIL at runtime
- [x] [`f30d8d8f50`](https://github.com/colesbury/nogil-3.12/commit/f30d8d8f50) Add pyatomic.h
- [x] ~~[`385eb1d99c`](https://github.com/colesbury/nogil-3.12/commit/385eb1d99c) pyport: add new macros~~
- [x] ~~[`de2be447b3`](https://github.com/colesbury/nogil-3.12/commit/de2be447b3) Make PyThreadState_GET thread-local~~
- [x] [`a24dc2ecc3`](https://github.com/colesbury/nogil-3.12/commit/a24dc2ecc3) pystate: keep track of attached vs. detached state
- [x] [`4584be5950`](https://github.com/colesbury/nogil-3.12/commit/4584be5950) parking_lot: add mutexes and one-time notifications
- [x] [`6845b133cc`](https://github.com/colesbury/nogil-3.12/commit/6845b133cc) critical_section: helpers for fine-grained locking (gh-111569)
- [ ] [`8ed62cab6a`](https://github.com/colesbury/nogil-3.12/commit/8ed62cab6a) pystate: use _PyRawMutex for internal mutexes (https://github.com/python/cpython/issues/111924)
- [ ] [`e15443b1f2`](https://github.com/colesbury/nogil-3.12/commit/e15443b1f2) ceval: move eval_breaker to per-thread state (#112175)
- [x] [`b6b12a9a94`](https://github.com/colesbury/nogil-3.12/commit/b6b12a9a94) Implement biased reference counting
- [ ] [`b6b12a9a94`](https://github.com/colesbury/nogil-3.12/commit/b6b12a9a94) Implement BRC inter-thread queue (#110481)
- [x] ~~[`7b6b6f1a01`](https://github.com/colesbury/nogil-3.12/commit/7b6b6f1a01) unicode: immortalize interned strings~~
- [x] ~~[`fc173e3711`](https://github.com/colesbury/nogil-3.12/commit/fc173e3711) unicode: always immortalize interned strings~~
- [ ] [`dd9b78460c`](https://github.com/colesbury/nogil-3.12/commit/dd9b78460c) Add safe memory reclamation scheme based on FreeBSD's GUS
- [x] [`901e134921`](https://github.com/colesbury/nogil-3.12/commit/901e134921) Add mimalloc v2.0.9 (DinoV)
- [ ] [`d13c63dee9`](https://github.com/colesbury/nogil-3.12/commit/d13c63dee9) pymem: remove uses of _PyMem_SetDefaultAllocator during finalization (https://github.com/python/cpython/issues/111924)
- [ ] [`654be8ffd6`](https://github.com/colesbury/nogil-3.12/commit/654be8ffd6) gc: make the garbage collector non-generational
- [ ] [`967fe31473`](https://github.com/colesbury/nogil-3.12/commit/967fe31473) gc: Traverese mimalloc heaps to find all objects.
- [ ] [`2864b6b36e`](https://github.com/colesbury/nogil-3.12/commit/2864b6b36e) Implement stop-the-world pauses (#111964)
- [ ] [`2864b6b36e`](https://github.com/colesbury/nogil-3.12/commit/2864b6b36e) gc: implement stop-the-world GC
- [ ] [`c1befd7689`](https://github.com/colesbury/nogil-3.12/commit/c1befd7689) Stop the world before fork() and Python shutdown
- [ ] [`82800d8ec8`](https://github.com/colesbury/nogil-3.12/commit/82800d8ec8) ceval: stop the world when enabling profiling/tracing for all threads
- [ ] [`7423dff344`](https://github.com/colesbury/nogil-3.12/commit/7423dff344) pystate: use stop-the-world in a few places
- [ ] [`86efa7dfe3`](https://github.com/colesbury/nogil-3.12/commit/86efa7dfe3) pystate: implement _PyRuntime.multithreaded
- [ ] [`d896dfc8db`](https://github.com/colesbury/nogil-3.12/commit/d896dfc8db) dict: make dict thread-safe (#112075)
- [ ] [`df4c51f82b`](https://github.com/colesbury/nogil-3.12/commit/df4c51f82b) list: make list thread-safe (#112087)
- [ ] [`9c1f7ba1b4`](https://github.com/colesbury/nogil-3.12/commit/9c1f7ba1b4) mro: thread-safe MRO cache
- [x] [`7a7aca096b`](https://github.com/colesbury/nogil-3.12/commit/7a7aca096b) getargs.c: make parser_init thread-safe (#111956)
- [ ] [`0dddcb6f9d`](https://github.com/colesbury/nogil-3.12/commit/0dddcb6f9d) weakref: make weakrefs thread-safe without the GIL (#111926)
- [ ] [`410ba1036a`](https://github.com/colesbury/nogil-3.12/commit/410ba1036a) dtoa: make dtoa thread-safe (#111962)
- [ ] [`6540bf3e6a`](https://github.com/colesbury/nogil-3.12/commit/6540bf3e6a) unicode: make unicodeobject.c thread-safe (#111971)
- [ ] [`5d006db9fa`](https://github.com/colesbury/nogil-3.12/commit/5d006db9fa) codecs.c: fix race condition (#111972)
- [ ] [`d1b5ed128e`](https://github.com/colesbury/nogil-3.12/commit/d1b5ed128e) _threadmodule: make _thread.lock thread-safe
- [ ] [`cfc11bcb1a`](https://github.com/colesbury/nogil-3.12/commit/cfc11bcb1a) typeobject: thread safety
- [ ] [`cfecf6f4eb`](https://github.com/colesbury/nogil-3.12/commit/cfecf6f4eb) threading: remove _tstate_lock from threading.Thread
- [ ] [`74df7785f5`](https://github.com/colesbury/nogil-3.12/commit/74df7785f5) pyqueue: add internal queue data structure
- [ ] [`4450445f51`](https://github.com/colesbury/nogil-3.12/commit/4450445f51) pymem: add _PyMem_FreeQsbr
- [ ] [`7e60a01aee`](https://github.com/colesbury/nogil-3.12/commit/7e60a01aee) queue: make SimpleQueue thread-safe
- [ ] [`4ca2924f0d`](https://github.com/colesbury/nogil-3.12/commit/4ca2924f0d) set: make set thread-safe (#112069)
- [x] ~~[`3cfbc49229`](https://github.com/colesbury/nogil-3.12/commit/3cfbc49229) moduleobject: fix data races~~
- [ ] [`5722416ef5`](https://github.com/colesbury/nogil-3.12/commit/5722416ef5) _threadmodule: thread-safety fixes
- [ ] [`31ec6f0290`](https://github.com/colesbury/nogil-3.12/commit/31ec6f0290) pystate: refcount threads to handle race between interpreter shutdown and thread exit
- [ ] [`45bdd27ee5`](https://github.com/colesbury/nogil-3.12/commit/45bdd27ee5) threading: make _thread.lock thread-safe
- [ ] [`07f5f8c318`](https://github.com/colesbury/nogil-3.12/commit/07f5f8c318) slice: move slice_cache to per-thread state (#111968)
- [ ] [`ea1160c6d7`](https://github.com/colesbury/nogil-3.12/commit/ea1160c6d7) asyncio: fix race conditions in enter_task and leave_task
- [x] [`212fef480e`](https://github.com/colesbury/nogil-3.12/commit/212fef480e) object.c: fix race when accessing attributes and methods (#111789)
- [x] [`70856f126d`](https://github.com/colesbury/nogil-3.12/commit/70856f126d) asdl: use _PyOnceFlag in Python-ast.c (#111956)
- [ ] [`360a79cb88`](https://github.com/colesbury/nogil-3.12/commit/360a79cb88) socketmodule.c: use relaxed atomics for global 'defaulttimeout'
- [x] [`041a08e339`](https://github.com/colesbury/nogil-3.12/commit/041a08e339) functools: make lru_cache thread-safe (#112070)
- [ ] [`9bf62ffc4b`](https://github.com/colesbury/nogil-3.12/commit/9bf62ffc4b) random: add a mutex to guard random.Random (#112071)
- [x] [`a8251a8d25`](https://github.com/colesbury/nogil-3.12/commit/a8251a8d25) clinic: support '@' syntax for recursive mutexes (#111903)
- [ ] [`ffade9d6f6`](https://github.com/colesbury/nogil-3.12/commit/ffade9d6f6) bufferedio: add locks to make print() thread-safe (#111965)
- [x] [`5b83c16dcd`](https://github.com/colesbury/nogil-3.12/commit/5b83c16dcd) textio: add locks to make textio thread-safe (#111965)
- [x] [`6323ca60f9`](https://github.com/colesbury/nogil-3.12/commit/6323ca60f9) stringio: make stringio thread-safe (#111965)
- [ ] [`f1e4742eaa`](https://github.com/colesbury/nogil-3.12/commit/f1e4742eaa) deque: make most functions thread-safe (#112050)
- [ ] [`78825e0508`](https://github.com/colesbury/nogil-3.12/commit/78825e0508) importlib: fix data race in imports (PyImport_ImportModuleLevelObject)
- [ ] [`2f5c90a284`](https://github.com/colesbury/nogil-3.12/commit/2f5c90a284) semaphore.c: decrease count before release sem_lock
- [x] [`22eca6e215`](https://github.com/colesbury/nogil-3.12/commit/22eca6e215) sha1: make sha1module thread-safe (https://github.com/python/cpython/issues/111916)
- [x] [`ada9b73feb`](https://github.com/colesbury/nogil-3.12/commit/ada9b73feb) _struct: fix race condition in cache_struct_converter (#112062)
- [ ] [`0e0b3899d1`](https://github.com/colesbury/nogil-3.12/commit/0e0b3899d1) signalmodule: fix thread-safety issue on macOS (Unclear if this is still an issue on macOS)
- [x] [`964bb33962`](https://github.com/colesbury/nogil-3.12/commit/964bb33962) json: make JSON scanner thread safe (https://github.com/python/cpython/issues/111928)
- [ ] [`86e7772c64`](https://github.com/colesbury/nogil-3.12/commit/86e7772c64) http: fix dependency on finalization order
- [ ] [`9ab96964e7`](https://github.com/colesbury/nogil-3.12/commit/9ab96964e7) faulthandler: don't dump all threads when running without the GIL
- [ ] [`cff32694a4`](https://github.com/colesbury/nogil-3.12/commit/cff32694a4) test_gdb: skip test_threads when running without GIL
- [ ] [`2ae5ee5ed4`](https://github.com/colesbury/nogil-3.12/commit/2ae5ee5ed4) tests: fix and work around some race conditions in tests
- [ ] [`9f9b3d085f`](https://github.com/colesbury/nogil-3.12/commit/9f9b3d085f) ceval: fix some thread-safety issues
- [ ] [`2a4c17e896`](https://github.com/colesbury/nogil-3.12/commit/2a4c17e896) pystate: move freelists to per-thread state (#111968)
- [ ] [`149ea9dc43`](https://github.com/colesbury/nogil-3.12/commit/149ea9dc43) Deferred reference counting
- [ ] [`7e7568672d`](https://github.com/colesbury/nogil-3.12/commit/7e7568672d) specialize: make specialization thread-safe
- [ ] [`90d34f0d18`](https://github.com/colesbury/nogil-3.12/commit/90d34f0d18) specialize: optimize for single-threaded programs
- [ ] [`42d3e11d8c`](https://github.com/colesbury/nogil-3.12/commit/42d3e11d8c) code: make code object use deferred reference counting
- [ ] [`c9fc49666c`](https://github.com/colesbury/nogil-3.12/commit/c9fc49666c) test: add support for checking for TSAN
- [ ] [`7507a77a98`](https://github.com/colesbury/nogil-3.12/commit/7507a77a98) thread: don't use sem_clockwait with TSAN
- [ ] [`a62d37674c`](https://github.com/colesbury/nogil-3.12/commit/a62d37674c) _posixsubprocess: disable vfork when running with ASAN
- [ ] [`398204d57b`](https://github.com/colesbury/nogil-3.12/commit/398204d57b) object: fix reported TSAN races
- [ ] [`4526c07cae`](https://github.com/colesbury/nogil-3.12/commit/4526c07cae) Disable the GIL by default in `--disable-gil` builds
2 Likes
smontanaro
(Skip Montanaro)
November 22, 2023, 12:43pm
127
Thanks. I now recall that, but must have lost track of it with all the other chit-chat (a couple threads with ~250 posts).