我在 C++ 应用程序中添加了一个 python 编辑器。为了能够在用户按下 ctrl-c 时停止 python 进程,我有 2 个线程:
1-第一个运行python字符串;
2-第二个轮询键盘以检查键盘中断。
我使用微软并发库来创建线程:
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 异常正确破坏?