Supporting Per-Interpreter GIL from Rust (PyO3)

Methinks building on noGIL here is putting the cart before the horse. NoGIL will take years to stabilize, and I expect you won’t be able to count on it existing for the next 4-5 releases.

after any call into unknown C code you might have been swapped onto a different subinterpreter

After a call into C from where? Python code can definitely be swapped to a different OS thread whenever it blocks for the GIL. But the mapping between Python threads and Python interpreter state is, was, and will always be fixed. Interpreters are not tied to OS threads.

The only time you could be swapped to a different (sub)interpreter, I think, would be when you’re executing C code without holding the GIL, and you make a call into something that does something with threads and/or the GIL.

I agree it’s surprising that the default API for running code in a different subinterpreter runs it in the current OS thread. But that’s how it’s always been for subinterpreters (pre GIL-per-interpreter).

I would like to see a new API to run some code in a different interpreter using a different OS thread. I am hoping that someone comes up with a SubinterpreterPoolExecutor that works like ProcessPoolExecutor but maintains a pool of subinterpreters to which it can dispatch functions. (Certain kinds of named functions can be pickled – the unpickling just re-imports it by name.) It could use a more efficient protocol than pickle in some cases. The main advantage IMO is that you don’t have to learn a new API.