2015-01-16 3 views
2

부스트 파이썬을 통해 파이썬 메소드가 호출 된 후 실행중인 파이썬 인터프리터를 중지 할 수있는 방법이 있습니까 C++ 내에 있습니까?부스트 파이썬 : 인터프리터를 중지하십시오

나는이 이유를 위해 전화를 중단 할 :

  1. 시간 제한 기간이 만료 된 경우 (즉, 스크립트는 "너무 오래"실행).
  2. 다른 (병렬 실행중인) Python 스크립트가 실패한 경우. "

아무것도를 설정하지만, 다른 한편으로는 내가 가끔 부스트 문서의 오른쪽 단락을 찾기 위해 투쟁하지 않은 웹 및 부스트 문서의 내 검색 ...

만 아이디어의 일종 "나는 이것을 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()의 실행을 중지 중단 할 수 있습니까? 내가 호출하는 방법이 가능하지 않다면 Boost Python으로 파이썬 함수를 호출하는 또 다른 방법이 있습니까? 은 통화를 중단 할 수 있습니까?

저는 리눅스에서 실행되고 있습니다 (일부 플랫폼 종속적 인 솔루션을 사용할 수있는 경우에 대비해 완전히 멋진 것입니다).

답변

3

나는 이 아니며은 진정한 "외부로부터의 통역 중지"접근법을 발견했습니다. 하지만 나는 내 상황에서 최소한 작업을 완료하는 해결 방법을 만들었습니다. 어쩌면 그것은 다른 사람을 도울 것입니다 ...

아이디어는 다른 것을하지는 않지만 깨어나기를 기다리는 파이썬 스크립트 안에 스레드가 있다는 것입니다. 그것은 C++ 내에서 "abort"함수 호출에 의해 깨어납니다. 깨어나면 스크립트가 내부에서 제거됩니다. 나는이 예에서 스크립트를 중지 원유 접근 방식을 선택했다 :

os._exit(1)

이 작업을 수행 할 수 있는지 더 좋은 방법이있다, 그러나 이것은 바로 여기에 지점을 넘어이다. 전체 중단 및 종료 물건도 멋지게 래핑 될 수 있지만 다시 한번 : 나는 그저 아이디어를 스케치하고 싶습니다.

내 테스트 파이썬은 스크립트는 다음과 같습니다 AcquireGIL이 같은보고와

// 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 */); 

:

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

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() 

이 같은 스크립트를 죽일

편집 내 스크립트의 입력 기능에서

다른 (유사) 방식

나는 도우미 함수를 호출 데몬로 스레드를 시작합니다. 도우미 함수는 worker 메소드를 호출한다. 작업자 메서드가 반환 된 후 도우미는 조건 변수를 알립니다. 주 스레드는이 상태를 기다립니다. 나가 외부에서 중단하고 싶은 경우에, 나는 다만 조건을 또한 통지한다. 주 스레드가 끝나면 도우미 스레드가 이미 종료되었거나 외부에서 중단 한 경우 정리됩니다.

주의

중단의 경우에는 도우미 스레드가 제대로 정리 할 수 ​​없습니다. 그래서 당신은 그것에 대처하거나 그것을 수동으로 돌봐야합니다.

+0

'os._exit (1)'을 중단 함수에 넣지 않는 이유는 무엇입니까? 'os._exit (1)'은 엔트리 포인트 컨텍스트 (즉, 중단되기를 기다리는 스레드로부터의)에서 호출되는 경우에만 작동합니까? –

+0

@ peschü : 예, (C++) 스레드에서 직접'os._exit (1) '을 호출 할 수 있다고 생각합니다. 나는 인터프리터를 더 정상적으로 멈추고 전체 프로세스 (C++ 프레임 포함)를 종료하려고했던 이전 접근법에서 여분의 스레드가 생겼다고 생각한다. 그것이 "다른 (비슷한) 접근법"이 성취하려고 시도한 것입니다. 파이썬 코드가 멈추는 동안 C++ 응용 프로그램이 계속 실행됩니다. – DrP3pp3r

관련 문제