Boost Python:停止interp

2024-10-01 11:37:07 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有办法阻止Python解释器在Python方法中从Boost Python中从<强> C++中调用?在

我想打断通话有两个原因:

  1. 如果超时时间过期(即脚本运行“太长”)。在
  2. 如果另一个(并行运行)Python脚本失败。在

我在网上和Boost文档中的搜索没有找到任何东西,但另一方面,我有时很难在Boost文档中找到正确的段落。。。在

我从这个StackOverflow question得到的唯一“某种想法”。这个想法是向脚本发送一个信号,但是当解释器在我的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 imp\n"
    << "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()之后,是否可以中断/中止pythonFunction()的执行? 如果我调用它的方式是不可能的,有没有其他方法可以用boostpython调用Python函数,这样我就可以中止调用了?在

我在Linux下运行(以防这会启用一些依赖于平台的解决方案,我会非常喜欢)。在


Tags: to方法文档脚本string解释器impboost
1条回答
网友
1楼 · 发布于 2024-10-01 11:37:07

我找到了一个真正的“从外部阻止翻译”的方法。但我创造了一个解决办法,至少能在我的情况下完成任务。也许它会帮助别人。。。在

我的想法是在Python脚本中有一个线程,它除了等待被唤醒之外什么也不做。它会被C++中的“中止”函数调用唤醒。一旦它醒来,它就会从内部杀死脚本。我选择了一种粗略的方法来停止这个示例中的脚本:

os._exit(1)

当然有更好的方法来做到这一点,但这已经超出了重点。整个中止和终止的东西也可以包装得更好,但再一次:我只想简述一下这个想法。在

我的测试脚本如下所示:

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++ +>强>我这样杀死脚本:

^{pr2}$

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_);
}

编辑

不同(类似)方法

在脚本的entry函数中,我启动一个线程作为daemon调用一个helper函数。helper函数调用一个worker方法(它执行我实际上想要做的事情)。worker方法返回之后,helper向条件变量发出信号。主线程只是等待这个条件。如果我想从外面流产,我也会通知情况。当主线程结束时,辅助线程已经结束或者在外部中止的情况下,将被清理。在

注意

在中止的情况下,助手线程将无法正确清理。所以你必须处理或手动处理。在

相关问题 更多 >