@@ -237,31 +237,259 @@ global data. All the details can be found in the CPython documentation.
237
237
238
238
Creating two concurrent ``scoped_interpreter `` guards is a fatal error. So is
239
239
calling ``initialize_interpreter `` for a second time after the interpreter
240
- has already been initialized.
240
+ has already been initialized. Use :class: `scoped_subinterpreter ` to create
241
+ a sub-interpreter. See :ref: `subinterp ` for important details on sub-interpreters.
241
242
242
243
Do not use the raw CPython API functions ``Py_Initialize `` and
243
244
``Py_Finalize `` as these do not properly handle the lifetime of
244
245
pybind11's internal data.
245
246
246
247
247
- Sub-interpreter support
248
- =======================
248
+ .. _subinterp :
249
+
250
+ Embedding Sub-interpreters
251
+ ==========================
252
+
253
+ A sub-interpreter is a separate interpreter instance which provides a
254
+ separate, isolated interpreter environment within the same process as the main
255
+ interpreter. Sub-interpreters are created and managed with a separate API from
256
+ the main interpreter. Beginning in Python 3.12, sub-interpreters each have
257
+ their own Global Interpreter Lock (GIL), which means that running a
258
+ sub-interpreter in a separate thread from the main interpreter can achieve true
259
+ concurrency.
260
+
261
+ pybind11's sub-interpreter API can be found in ``pybind11/subinterpreter.h ``.
262
+
263
+ pybind11 :class: `subinterpreter ` instances can be safely moved and shared between
264
+ threads as needed. However, managing multiple threads and the lifetimes of multiple
265
+ interpreters and their GILs can be challenging.
266
+ Proceed with caution (and lots of testing)!
267
+
268
+ The main interpreter must be initialized before creating a sub-interpreter, and
269
+ the main interpreter must outlive all sub-interpreters. Sub-interpreters are
270
+ managed through a different API than the main interpreter.
271
+
272
+ The :class: `subinterpreter ` class manages the lifetime of sub-interpreters.
273
+ Instances are movable, but not copyable. Default constructing this class does
274
+ *not * create a sub-interpreter (it creates an empty holder). To create a
275
+ sub-interpreter, call :func: `subinterpreter::create() `.
276
+
277
+ .. warning ::
278
+
279
+ Sub-interpreter creation acquires (and subsequently releases) the main
280
+ interpreter GIL. If another thread holds the main GIL, the function will
281
+ block until the main GIL can be acquired.
282
+
283
+ Sub-interpreter destruction temporarily activates the sub-interpreter. The
284
+ sub-interpreter must not be active (on any threads) at the time the
285
+ :class: `subinterpreter ` destructor is called.
286
+
287
+ Both actions will re-acquire any interpreter's GIL that was held prior to
288
+ the call before returning (or return to no active interpreter if none was
289
+ active at the time of the call).
290
+
291
+ Each sub-interpreter will import a separate copy of each ``PYBIND11_EMBEDDED_MODULE ``
292
+ when those modules specify a ``multiple_interpreters `` tag. If a module does not
293
+ specify a ``multiple_interpreters `` tag, then Python will report an ``ImportError ``
294
+ if it is imported in a sub-interpreter.
295
+
296
+ pybind11 also has a :class: `scoped_subinterpreter ` class, which creates and
297
+ activates a sub-interpreter when it is constructed, and deactivates and deletes
298
+ it when it goes out of scope.
299
+
300
+ Activating a Sub-interpreter
301
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
302
+
303
+ Once a sub-interpreter is created, you can "activate" it on a thread (and
304
+ acquire its GIL) by creating a :class: `subinterpreter_scoped_activate `
305
+ instance and passing it the sub-intepreter to be activated. The function
306
+ will acquire the sub-interpreter's GIL and make the sub-interpreter the
307
+ current active interpreter on the current thread for the lifetime of the
308
+ instance. When the :class: `subinterpreter_scoped_activate ` instance goes out
309
+ of scope, the sub-interpreter GIL is released and the prior interpreter that
310
+ was active on the thread (if any) is reactivated and it's GIL is re-acquired.
311
+
312
+ When using ``subinterpreter_scoped_activate ``:
313
+
314
+ 1. If the thread holds any interpreter's GIL:
315
+ - That GIL is released
316
+ 2. The new sub-interpreter's GIL is acquired
317
+ 3. The new sub-interpreter is made active.
318
+ 4. When the scope ends:
319
+ - The sub-interpreter's GIL is released
320
+ - If there was a previous interpreter:
321
+ - The old interpreter's GIL is re-acquired
322
+ - The old interpreter is made active
323
+ - Otherwise, no interpreter is currently active and no GIL is held.
324
+
325
+ Example:
326
+
327
+ .. code-block :: cpp
328
+
329
+ py::initialize_interpreter();
330
+ // Main GIL is held
331
+ {
332
+ py::subinterpreter sub = py::subinterpreter::create();
333
+ // Main interpreter is still active, main GIL re-acquired
334
+ {
335
+ py::subinterpreter_scoped_activate guard(sub);
336
+ // Sub-interpreter active, thread holds sub's GIL
337
+ {
338
+ py::subinterpreter_scoped_activate main_guard(py);
339
+ // Sub's GIL was automatically released
340
+ // Main interpreter active, thread holds main's GIL
341
+ }
342
+ // Back to sub-interpreter, thread holds sub's GIL again
343
+ }
344
+ // Main interpreter is active, main's GIL is held
345
+ }
346
+
347
+
348
+ GIL API for sub-interpreters
349
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
350
+
351
+ :class: `gil_scoped_release ` and :class: `gil_scoped_acquire ` can be used to
352
+ manage the GIL of a sub-interpreter just as they do for the main interpreter.
353
+ They both manage the GIL of the currently active interpreter, without the
354
+ programmer having to do anything special or different. There is one important
355
+ caveat:
356
+
357
+ .. note ::
358
+
359
+ When no interpreter is active through a
360
+ :class: `subinterpreter_scoped_activate ` instance (such as on a new thread),
361
+ :class: `gil_scoped_acquire ` will acquire the **main ** GIL and
362
+ activate the **main ** interpreter.
363
+
364
+
365
+ Full Sub-interpreter example
366
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
367
+
368
+ Here is an example showing how to create and activate sub-interpreters:
369
+
370
+ .. code-block :: cpp
371
+
372
+ #include <iostream>
373
+ #include <pybind11/embed.h>
374
+ #include <pybind11/subinterpreter.h>
375
+
376
+ namespace py = pybind11;
377
+
378
+ PYBIND11_EMBEDDED_MODULE(printer, m, py::multiple_interpreters::per_interpreter_gil()) {
379
+ m.def("which", [](const std::string& when) {
380
+ std::cout << when << "; Current Interpreter is "
381
+ << py::subinterpreter::current().id()
382
+ << std::endl;
383
+ });
384
+ }
385
+
386
+ int main() {
387
+ py::scoped_interpreter main_interp;
388
+
389
+ py::module_::import("printer").attr("which")("First init");
390
+
391
+ {
392
+ py::subinterpreter sub = py::subinterpreter::create();
393
+
394
+ py::module_::import("printer").attr("which")("Created sub");
395
+
396
+ {
397
+ py::subinterpreter_scoped_activate guard(sub);
398
+ try {
399
+ py::module_::import("printer").attr("which")("Activated sub");
400
+ }
401
+ catch (py::error_already_set &e) {
402
+ std::cerr << "EXCEPTION " << e.what() << std::endl;
403
+ return 1;
404
+ }
405
+ }
406
+
407
+ py::module_::import("printer").attr("which")("Deactivated sub");
408
+
409
+ {
410
+ py::gil_scoped_release nogil;
411
+ {
412
+ py::subinterpreter_scoped_activate guard(sub);
413
+ try {
414
+ {
415
+ py::subinterpreter_scoped_activate main_guard(py::subinterpreter::main());
416
+ try {
417
+ py::module_::import("printer").attr("which")("Main within sub");
418
+ }
419
+ catch (py::error_already_set &e) {
420
+ std::cerr << "EXCEPTION " << e.what() << std::endl;
421
+ return 1;
422
+ }
423
+ }
424
+ py::module_::import("printer").attr("which")("After Main, still within sub");
425
+ }
426
+ catch (py::error_already_set &e) {
427
+ std::cerr << "EXCEPTION " << e.what() << std::endl;
428
+ return 1;
429
+ }
430
+ }
431
+ }
432
+ }
433
+
434
+ py::module_::import("printer").attr("which")("At end");
435
+
436
+ return 0;
437
+ }
438
+
439
+ Expected output:
440
+
441
+ .. code-block :: text
442
+
443
+ First init; Current Interpreter is 0
444
+ Created sub; Current Interpreter is 0
445
+ Activated sub; Current Interpreter is 1
446
+ Deactivated sub; Current Interpreter is 0
447
+ Main within sub; Current Interpreter is 0
448
+ After Main, still within sub; Current Interpreter is 1
449
+ At end; Current Interpreter is 0
450
+
451
+ .. warning ::
452
+
453
+ In Python 3.12 sub-interpreters must be destroyed in the same OS thread
454
+ that created them. Failure to follow this rule may result in deadlocks
455
+ or crashes when destroying the sub-interpreter on the wrong thread.
456
+
457
+ This constraint is not present in Python 3.13+.
458
+
459
+
460
+ Best Practices for sub-interpreter safety
461
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
462
+
463
+ - Never share Python objects across different interpreters.
464
+
465
+ - :class: `error_already_set ` objects contain a reference to the Python exception type,
466
+ and :func: `error_already_set::what() ` acquires the GIL. So Python exceptions must
467
+ **never ** be allowed to propagate past the enclosing
468
+ :class: `subinterpreter_scoped_activate ` instance!
469
+ (So your try/catch should be *just inside * the scope covered by the
470
+ :class: `subinterpreter_scoped_activate `.)
471
+
472
+ - Avoid global/static state whenever possible. Instead, keep state within each interpreter,
473
+ such as within the interpreter state dict, which can be accessed via
474
+ ``subinterpreter::current().state_dict() ``, or within instance members and tied to
475
+ Python objects.
476
+
477
+ - Avoid trying to "cache" Python objects in C++ variables across function calls (this is an easy
478
+ way to accidentally introduce sub-interpreter bugs). In the code example above, note that we
479
+ did not save the result of :func: `module_::import `, in order to avoid accidentally using the
480
+ resulting Python object when the wrong interpreter was active.
249
481
250
- Creating multiple copies of ``scoped_interpreter `` is not possible because it
251
- represents the main Python interpreter. Sub-interpreters are something different
252
- and they do permit the existence of multiple interpreters. This is an advanced
253
- feature of the CPython API and should be handled with care. pybind11 does not
254
- currently offer a C++ interface for sub-interpreters, so refer to the CPython
255
- documentation for all the details regarding this feature.
482
+ - Avoid moving or disarming RAII objects managing GIL and sub-interpreter lifetimes. Doing so can
483
+ lead to confusion about lifetimes. (For example, accidentally extending a
484
+ :class: `subinterpreter_scoped_activate ` past the lifetime of it's :class: `subinterpreter `.)
256
485
257
- We'll just mention a couple of caveats the sub-interpreters support in pybind11:
486
+ - While sub-interpreters each have their own GIL, there can now be multiple independent GILs in one
487
+ program so you need to consider the possibility of deadlocks caused by multiple GILs and/or the
488
+ interactions of the GIL(s) and your C++ code's own locking.
258
489
259
- 1. Sub-interpreters will not receive independent copies of embedded modules.
260
- Instead, these are shared and modifications in one interpreter may be
261
- reflected in another.
490
+ - When using multiple threads to run independent sub-interpreters, the independent GILs allow
491
+ concurrent calls from different interpreters into the same C++ code from different threads.
492
+ So you must still consider the thread safety of your C++ code. Remember, in Python 3.12
493
+ sub-interpreters must be destroyed on the same thread that they were created on.
262
494
263
- 2. Managing multiple threads, multiple interpreters and the GIL can be
264
- challenging and there are several caveats here, even within the pure
265
- CPython API (please refer to the Python docs for details). As for
266
- pybind11, keep in mind that ``gil_scoped_release `` and ``gil_scoped_acquire ``
267
- do not take sub-interpreters into account.
495
+ - Familiarize yourself with :ref: `misc_concurrency `.
0 commit comments