如果我将Python解释器嵌入到C或C ++程序中,就像在this example中那样,有没有办法限制解释器运行的时间?有没有什么可以阻止Python代码进入无限循环,从而阻止PyObject_CallObject
(或等价物)返回?
同样,如果Python代码创建了一个新线程,是否还有什么可以阻止这个线程进入无限循环并永远运行?
答案 0 :(得分:7)
正如您在the docs中所看到的,PyObject_CallObject
没有限制函数运行时间的机制。我也知道没有Python C API函数可以暂停或终止解释器使用的线程。
因此,我们必须在如何阻止线程运行方面更具创造性。我可以想到你可以做到的3种方法(从最安全/最干净到最危险......
这里的想法是你的Python函数可以运行很长时间只是调用主应用程序中的另一个函数,使用C API来查看它是否应该关闭。一个简单的True / False结果可以让你优雅地终止。
这是最安全的解决方案,但要求您更改Python代码。
由于您正在嵌入Interpreter,因此您已经在使用C API,因此可以使用PyThreadState_SetAsyncExc强制在违规线程中引发异常。您可以找到使用此API here的示例。虽然它是Python代码,但同样的功能可以在您的主应用程序中使用。
这个解决方案不太安全,因为它要求代码不要捕获异常并在之后保持可用状态。
我不打算进入这个,因为它本身就是不安全的。有关原因的解释,请参阅Is there any way to kill a Thread in Python?。
答案 1 :(得分:2)
如果在某些实时系统中需要控制滞后和抖动,请嵌入“StacklessPython” - 支持协同例程的Python。用于“Twisted Web Server”。
答案 2 :(得分:1)
我希望能够中断任何正在运行的Python代码块,包括取消无限循环或仅删除一些长时间运行的代码。在我的应用程序中,提交并评估了单线程Python代码。中断请求可以随时出现。这个问题和答案对于帮助我真正实现目标至关重要。
我使用2016年7月以来@Peter Brittain回答的中间方法。
启动Python引擎后,我使用Python代码中的threading
包检索线程ID。我将其解析为c long值并将其保存。
中断功能实际上非常简单:
PyGILState_Ensure()
PyThreadState_SetAsyncExc(threadId, PyExc_Exception)
使用我之前保存的线程ID和通用异常类型
PyGILState_Release()
因此,感谢您同时回答原始问题和Peter Brittain!