Boost Python:停止解释器
Boost Python: stop interpreter
在C++中通过Boost Python调用Python方法后,有没有办法停止正在运行的Python解释器?
我想打断通话有两个原因:
- 如果超时期限已过期(即脚本运行"太长")。
- 如果另一个(并行运行的)Python 脚本失败。
我在 Web 和 Boost 文档中的搜索没有找到任何东西,但另一方面,我有时很难在 Boost 文档中找到正确的段落......
我从这个StackOverflow问题中得到的唯一"想法"。这个想法是向脚本发送信号,但是由于解释器在我的C++进程中运行,这可能不是一个可行的选择?!
我正在执行以下操作:
const boost::filesystem::path pythonScriptPath = /* Path to the script I want to execute a function from. */
const std::string pythonFunctionName = /* Name of the Python function to call. */;
boost::python::object mainModule = boost::python::import("__main__");
boost::python::object mainNameSpace = mainModule.attr("__dict__");
boost::python::dict locals;
locals["moduleName"] = pythonScriptPath.stem().string();
locals["modulePath"] = pythonScriptPath.string();
std::stringstream importModuleStream;
importModuleStream
<< "import impn"
<< "newModule = imp.load_module(moduleName, open(modulePath), modulePath, ('py', 'U', imp.PY_SOURCE))n";
boost::python::exec(importModuleStream.str().c_str(), mainNameSpace, locals);
auto pythonScript = locals["newModule"];
auto pythonFunction = pythonScript_.attr(pythonFunctionName .c_str());
pythonFunction(/* args */);
现在的问题是:
我可以在触发pythonFunction()后中断/中止它的执行吗?如果不可能以我调用它的方式,是否有另一种方法可以使用 Boost Python 调用 Python 函数,以便我可以中止调用?
我在 Linux 下运行(以防万一这启用了一些依赖于平台的解决方案,我会非常酷)。
我还没有找到真正的"从外部停止解释器"的方法。但我创建了一个解决方法,至少可以在我的情况下完成工作。也许它会帮助其他人...
这个想法是我在 Python 脚本中有一个线程,它什么都不做,只是等待被唤醒。它通过从C++内部调用"中止"函数来唤醒。一旦它被唤醒,它就会从内部杀死脚本。在此示例中,我选择了一种粗略的方法来停止脚本:
os._exit(1)
肯定有更好的方法可以做到这一点,但这超出了这里的重点。整个中止和终止的东西也可以包装得更好,但再一次:我只想勾勒出这个想法。
我的测试Python脚本如下所示:
import threading
import time
import os
def abort():
global run
run = False
global condition
with condition:
condition.notify()
def threadBlock():
while True:
print( "Blocking!" )
time.sleep(3)
def threadTerminate():
while run:
global condition
with condition:
condition.wait()
global kill
if kill:
os._exit(1)
def myEntryFunction()
blockingThread = threading.Thread( target = threadBlock )
terminatingThread = threading.Thread( target = threadTerminate )
blockingThread.start()
terminatingThread.start()
threadBlock().join()
global kill
kill = False
global condition
with condition:
condition.notify()
terminatingThread.join()
run = True;
kill = True;
condition = threading.Condition()
从C++内部,我像这样杀死脚本:
// other code (see question)
std::thread killer([&pythonScript] () {
std::chrono::seconds d(15);
std::this_thread::sleep_for(d);
AcquireGIL gil;
pythonScript.executeFunction("abort");
});
pythonFunction(/* args */);
AcquireGIL看起来像这样:
#include <boost/python.hpp>
class AcquireGIL final
{
public:
AcquireGIL();
~AcquireGIL();
private:
PyGILState_STATE gilState_;
};
AcquireGIL::AcquireGIL()
: gilState_(PyGILState_Ensure()) {
// nothing to do...
}
AcquireGIL::~AcquireGIL() {
PyGILState_Release(gilState_);
}
编辑
不同(相似)的方法
在我的脚本的入口函数中,我启动一个线程作为守护程序调用帮助程序函数。帮助程序函数调用一个工作器方法(它执行我实际想要做的事情)。工作器方法返回后,帮助程序会发出条件变量的信号。主线程只是等待这种情况。如果我想从外面流产,我也只是通知条件。当主线程结束时,将清理已经结束的帮助程序线程,或者在从外部中止的情况下。
注意力
如果中止,帮助程序线程将无法正确清理。因此,您必须应对或手动处理它。
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- Pybind11:将元组列表从Python传递到C++
- 如何在c++中使用引用实现类似python的行为
- 从嵌入式解释器捕获 python 窗口输出C++
- 在C++中嵌入 Python:解释器在执行过程中的持久性
- 如何中断嵌入C++应用程序中的python解释器
- 使用自定义模块构建 python 解释器时出现问题
- 如何使用C++的字节码优化初始化嵌入式 Python 解释器
- 用c++对象的全局实例扩展嵌入式python解释器
- boost.python 解释器实例化
- Boost Python:停止解释器
- 如何允许通过嵌入式 Python 解释器中调用的脚本导入第三方库
- 如何为嵌入式python解释器设置工作目录
- Python C API使用WinPython Python解释器而不是标准Python解释器
- 向python嵌入式解释器公开c++类实例
- 加载DLL时Python解释器退出
- c++ Python解释器——Py_Initialize正在崩溃
- c++中嵌入式python的Matplotlib和子解释器
- 如何在VIM中指定Python解释器版本
- 从python解释器中调用一个方法