Я добавляю редактор Python в приложение C ++. Чтобы иметь возможность остановить процесс Python, когда пользователь нажимает Ctrl-C, у меня есть 2 потока:
1- первый запускает строку питона;
2 — второй опрашивает клавиатуру, чтобы проверить ее прерывание.
Я использую библиотеку параллелизма Microsoft для создания потоков:
auto task1 = Concurrency::make_task([&]
{
task1_id = GetCurrentThreadId();
Run(Script);
bFinish = true;
});
auto task2 = Concurrency::make_task([&]
{
while(true)
{
if ((GetKeyState (0x43) < 0 && (GetKeyState (VK_CONTROL) < 0)) && task1_id != 0)
{
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
int t = PyThreadState_SetAsyncExc(task1_id,PyExc_KeyboardInterrupt);
PyGILState_Release(gstate);
break;
}
else if(bFinish)
{
break;
}
else
{
Sleep(10);
}
}
});
m_tasks.run(task2);
Concurrency::task_group_status test = m_tasks.run_and_wait(task1);
Это обычно работает довольно хорошо. Если происходит событие ctrl-c, событие «клавиатурное прерывание» произойдет в «потоке скрипта», и все остановится.
Проблема возникает, когда я использую matplotlib для создания фигуры и отправляю событие ctrl-c, пока фигуры еще открыты. Событие остановит все как раньше, но окна tkinter не будут уничтожены, и нажатие на них вызовет ошибку времени выполнения:
Fatal Python error: PyEval_RestoreThread: NULL tstate
Можно ли каким-то образом заставить эти окна должным образом уничтожить исключение keybordinterrupt?
Задача ещё не решена.
Других решений пока нет …