python/cpython

Refer to the GIL as a thread state in the C API

Opened this issue · 0 comments

Documentation

"The GIL" is used all over the place in the C API documentation, but it's not really correct, and is a bit misleading for users. The biggest issue is that for free-threading, there is no GIL, so users erroneously call the C API inside Py_BEGIN_ALLOW_THREADS blocks or omit PyGILState_Ensure in fresh threads. Similarly, PEP-684 let's us have multiple GILs. Which one is "the" GIL?

Really, what "holding the GIL" should actually mean these days, is having an attached thread state (which also means holding the GIL for an interpreter on default builds). Thread states are documented, but not well. As far as I can tell, users know very little about them, other than that they hold some thread-specific information. That isn't great, because basically the only way to use subinterpreters right now is with thread state shenanigans, and the free-threading problem I mentioned above is also an issue.

Documenting them better, and replacing phrases like "the caller must hold the GIL" with "the caller must have an attached thread state" should help users understand both subinterpreters and nogil better. This will be a decently big change to the documentation, though. Right now, we're sort of all over the place in what a thread state means. From PyInterpreterState_Get

Get the current interpreter.
Issue a fatal error if there no current Python thread state or no current interpreter. It cannot return NULL.
The caller must hold the GIL.

Most of this is redundant. If there is no thread state, that implies that there isn't an interpreter, and therefore can't hold a GIL. Redundant differences like this make it seem like there is a meaningful difference (for users) between an attached thread state and holding the GIL, which isn't good.

I have a PR ready (which I'll submit as a draft), but I'm putting this up for discussion first, because I'm not too sure how people will feel about it.

Linked PRs