Ant*_* L. 23 python multithreading process embedded-language python-c-api
我正在将Python解释器嵌入到C程序中.但是,可能会发生这样的情况:运行某些python脚本时PyRun_SimpleString()会遇到无限循环或执行太长时间.考虑PyRun_SimpleString("while 1: pass");在阻止主程序阻止我认为我可以在一个线程中运行解释器.
如何停止在线程中运行的嵌入式解释器中执行python脚本而不会终止整个过程?
是否可以将异常传递给解释器?我应该将脚本包装在其他可以收听信号的脚本下吗?
PS:我可以在一个单独的过程中运行python,但这不是我想要的 - 除非它是最后的手段......
更新:
所以,它现在有效.再次感谢Denis Otkidach!
如果我看到这一点,你必须做两件事:告诉解释器停止并return -1在与PyRun_SimpleString()运行的同一个线程中.
要停止,有一些可能性:PyErr_SetString(PyExc_KeyboardInterrupt, "...")或者PyErr_SetInterrupt()- 第一个可能让Python运行更多指令然后停止,后者立即停止执行.
要return -1使用Py_AddPendingCall()注入一个函数调用成Python执行.自2.7和3.1版以来,文档提到它,但它也运行在早期的Pythons上(这里是2.6).从2.7和3.1它也应该是线程安全的,这意味着你可以在不获取GIL(?)的情况下调用它.
所以可以重写下面的例子:
int quit() {
PyErr_SetInterrupt();
return -1;
}
Run Code Online (Sandbox Code Playgroud)
Den*_*ach 11
您可以使用Py_AddPendingCall()添加函数引发异常以在下一个检查间隔调用(有关sys.setcheckinterval()详细信息,请参阅文档).这是一个Py_Exit()调用的例子(这对我有用,但可能不是你需要的),用Py_Finalize()以下之一代替PyErr_Set*():
int quit(void *) {
Py_Exit(0);
}
PyGILState_STATE state = PyGILState_Ensure();
Py_AddPendingCall(&quit, NULL);
PyGILState_Release(state);
Run Code Online (Sandbox Code Playgroud)
对于任何纯python代码来说,这应该足够了.但请注意,一些C函数可以作为单个操作运行一段时间(有一个长时间运行的正则表达式搜索的例子,但我不确定它是否仍然相关).