Skip to content

Instantly share code, notes, and snippets.

@szabolcsdombi
Created October 4, 2023 17:29
Show Gist options
  • Save szabolcsdombi/cb4e6cda9ccd372bb038f2b717f764d0 to your computer and use it in GitHub Desktop.
Save szabolcsdombi/cb4e6cda9ccd372bb038f2b717f764d0 to your computer and use it in GitHub Desktop.
Running sub-interpreters in parallel with Python 3.12
#include <Windows.h>
#include <Python.h>
void worker(PyThreadState * tstate) {
PyThreadState_Swap(tstate);
PyRun_SimpleString("fib = lambda x: x if x < 2 else fib(x - 1) + fib(x - 2)");
PyRun_SimpleString("print(f'{fib(38) = }')");
}
PyThreadState * new_interpreter() {
PyInterpreterConfig config = {};
config.use_main_obmalloc = 0;
config.allow_fork = 0;
config.allow_exec = 0;
config.allow_threads = 0;
config.allow_daemon_threads = 0;
config.check_multi_interp_extensions = 1;
config.gil = PyInterpreterConfig_OWN_GIL;
PyThreadState * tstate = NULL;
PyThreadState * save_tstate = PyThreadState_Get();
PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config);
PyThreadState_Swap(save_tstate);
return tstate;
}
int main() {
PyConfig config = {};
// PyConfig_InitIsolatedConfig(&config);
PyConfig_InitPythonConfig(&config);
Py_InitializeFromConfig(&config);
const int num_threads = 4;
PyThreadState * interpreter[num_threads] = {};
for (int i = 0; i < num_threads; ++i) {
interpreter[i] = new_interpreter();
}
// PyThreadState_Swap(NULL);
HANDLE threads[num_threads] = {};
for (int i = 0; i < num_threads; ++i) {
threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)worker, interpreter[i], 0, NULL);
}
WaitForMultipleObjects(num_threads, threads, true, INFINITE);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment