Я бы предложил изменить схему взаимодействия между потоками.
Ваша текущая реализация работает следующим образом:
PyGILState_Ensure();
result = doDangerousThing(); // this could kill the thread
storeToPythonObject(result);
PyGILState_Release();
Вариант A, очевидный:
result = doDangerousThing(); // this could kill the thread
PyGILState_Ensure();
storeToPythonObject(result);
PyGILState_Release();
Вариант B, менее очевидный, см. [1] , [2] для идей:
/* worker_thread.c */
result = doDangerousThing(); // this could kill the thread
putToLocklessQueue(result, *queue_in_main_thread);
/* main_thread.c */
if (hasItems(my_lockless_queue)) {
PyGILState_Ensure();
while (hasItems(my_lockless_queue)) {
storeToPythonObject(popItem(my_lockless_queue));
}
PyGILState_Release();
// sleep again here
}