boostpython:停止解释器 有没有办法阻止Python解释器在Python方法中从Boost Python中调用< > C++ >?
我想中断通话有两个原因:boostpython:停止解释器 有没有办法阻止Python解释器在Python方法中从Boost Python中调用< > C++ >?,python,c++,linux,boost,boost-python,Python,C++,Linux,Boost,Boost Python,我想中断通话有两个原因: 如果超时时间已过(即脚本运行“过长”) 如果另一个(并行运行)Python脚本失败 我在web和Boost文档中的搜索没有找到任何结果,但另一方面,我有时很难在Boost文档中找到正确的段落 我从中得到的唯一“想法”。这个想法是向脚本发送一个信号,但是当解释器在我的C++进程中运行时,这可能不是一个可行的选项?!p> 我正在做以下工作: const boost::filesystem::path pythonScriptPath=/*我要从中执行函数的脚本的路径*/ c
const boost::filesystem::path pythonScriptPath=/*我要从中执行函数的脚本的路径*/
const std::string pythonFunctionName=/*要调用的Python函数的名称。*/;
boost::python::object mainModule=boost::python::import(“_umain__;”);
boost::python::object mainnespace=mainModule.attr(“_dict__”);
boost::python::dict局部变量;
局部变量[“moduleName”]=pythonScriptPath.stem().string();
局部变量[“modulePath”]=pythonScriptPath.string();
std::stringstream importModuleStream;
导入模块流
我还没有找到一种真正的“从外部阻止口译员”的方法。但我创造了一个变通办法,至少能在我的情况下完成工作。也许它会帮助其他人
我的想法是在Python脚本中有一个线程,它不做任何其他事情,只是等待唤醒。它会被C++中的“中止”函数调用唤醒。一旦它醒来,它就会从内部杀死脚本。在本例中,我选择了一种粗略的方法来停止脚本:
os.\u退出(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()
// 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 */);
在C++中,我这样终止脚本:
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()
// 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_);
}
#包括
期末考试
{
公众:
获得gil();
~gil();
私人:
皮吉州;
};
AcquireGIL::AcquireGIL()
:gilState(PyGILState_sure()){
//无事可做。。。
}
AcquireGIL::~AcquireGIL(){
PyGILState_发布(gilState_);
}
编辑
不同(相似)方法
在脚本的entry函数中,我启动了一个线程作为守护进程来调用helper函数。helper函数调用一个worker方法(该方法完成我真正想要做的事情)。worker方法返回后,helper将发出一个条件变量的信号。主线程只是等待这种情况。如果我想从外部中止,我也会通知条件。当主线程结束时,辅助线程已经结束,或者在外部中止的情况下,将被清除
注意
在中止的情况下,辅助线程将无法正确清理。因此,您必须手动处理该问题。为什么不将os.\u exit(1)
放入中止功能?os.\u exit(1)
只有在从入口点上下文(即从刚刚等待中止的线程)调用时才有效吗?@peschü:是的,我认为您可以直接从(C++)线程调用os.\u exit(1)
。我想额外的线索源于我尝试过的方法,我试图让解释器更优雅地终止,然后终止整个过程(包括C++框架)。这就是“不同(类似)方法”试图实现的:停止Python代码,而C++应用程序则保持运行。