2016-12-22 6 views
1

질문 앞에 약간의 문맥을 제공해야합니다. 나와 함께 견뎌주세요. boost :: python 사용하기 일부 예외 유형을 Python에 노출합니다 (예 : MyExceptionType). 나는 boomTest을 가지고 파이썬에 그것이 작동하는지 점검 할 것을 드러낸다. 파이썬은 boomTest을 호출하고 정확히 MyExceptionType을 처리합니다. 이것은 사물의 C++ 쪽 :파이썬이 C++ boost :: python :: error_already_set에 던져지는 것을 방지하는 방법?

static void boomTest() { 
    throw MyExceptionType("Smoked too many Cohibas!"); 
} 

static PyObject *myExceptionPtr = NULL; 
static void translate(MyExceptionType const &exception) { 
    assert(myExceptionPtr != NULL); 
    boost::python::object pythonExceptionInstance(exception); 
    PyErr_SetObject(myExceptionPtr, pythonExceptionInstance.ptr()); 
} 

BOOST_PYTHON_MODULE(test) { 
    class_<MyExceptionType> myException("MyExceptionType", no_init); 
    myException.add_property("message", &MyExceptionType::what); 
    myExceptionPtr = myException.ptr(); 
    register_exception_translator<MyExceptionType>(&translate); 
} 

그리고 이것은 사물의 파이썬 쪽 :

실제 사용 사례에서, 내가 파이썬에 콜백을 가지고 있기 때문에 지금
import sys 

import example 
reload(example) 
from example import MyExceptionType, boomTest 

def tryBoomTest(): 
    try: 
     boomTest() 

    except MyExceptionType as ex: 
     print 'Success! MyExceptionType gracefully handled:' \ 
      '\n message="%s"' % ex.message 
    except: 
     print 'Caught unhandled exception: %s "%s"' % (sys.exc_info()[0], sys.exc_info()[1]) 

상황이 조금 털이 얻을

# this is a Python callback invoked from a C++ boost non-Python thread 
def handle(future): 
    try: 
     # future.get() throws MyExceptionType if there was a cluster exception 
     "Cluster response received with value: %s" % future.get() 

    except MyExceptionType as ex: 
     print 'Success! MyExceptionType gracefully handled:' \ 
      '\n message="%s"' % ex.message 

그리고 이제 OP :는 C가 (비 파이썬) 스레드를 밀어 ++에서 다음과 같이

future.get() 호출이 파이썬이 처리 할 MyExceptionType을 던질 때 내 C++ 콜백 트리거가 boost::python::error_already_set 예외를 얻는 이유는 무엇입니까? 이 문제는 C++ (non-Python) 스레드 내에서 예외가 발생했기 때문에 발생하는 것으로 의심됩니다 ...

처음부터 예제와 같이 예외를 처리하도록하려면 무엇이 필요합니까?

나는 다음을 수행 ++ C에서 콜백 트리거 시도

:

void callbackTrigger() { 
    try { 
     pythonHandle_(getFuture()); 
    } 
    // why do I get this??? 
    catch (boost::python::error_already_set&) { 
     // this doesn't help, Python doesn't still handle MyExceptionType 
     boost::python::handle_exception(); 
    } 
} 

답변

1

내가 파이썬은 외계인의 일환으로 (심지어 파이썬 코드에서) 발생하지만 실행 예외를 처리 좋아하지 않는 대한 내 이론을 검증 C++ 스레드. 따라서 필자는 파이썬 기본 파이썬에서 콜백을 처리 할 수있는 순수 파이썬 래퍼를 만들었습니다.

import example 
reload(example) 
from example import MyExceptionType 

condition = threading.Condition() 
futures = [] 

# Actual handle executed by the main Python THREAD 
# __after__ submitting all the jobs to the Cluster 
# N is the number of jobs that were submitted to the Cluster 
def handle(N): 
    while (N > 0): 
     condition.acquire() 
     try: 
      # wait for max of a second to prevent this thread waiting indefinitely 
      # when it misses notify while being busy processing responses 
      condition.wait(1.0) 
      for future in futures: 
       try: 
        print 'callback received! the response is:\n %s' % future.get() 

       except MyExceptionType as ex: 
        print 'MyExceptionType gracefully handled:' \ 
          '\n message="%s"' % ex.message 
       except: 
        print 'Caught unhandled exception: %s "%s"' % (sys.exc_info()[0], sys.exc_info()[1]) 
     finally: 
      N -= len(futures) 
      del(futures[:]) 
      condition.release() 

# callback called from a C++ boost THREAD 
def callback(future): 
    condition.acquire() 
    try: 
     # do not consume the future here, rather let the main 
     # Python thread deal with it ... 
     futures.append(future) 
     condition.notify() 
    finally: 
     condition.release() 

는 적합하지 않습니다 그러나 작동하고 출력은 올바른 :

registering callback 1 ... 
registering callback 2 ... 
registering callback 3 ... 
registering callback 4 ... 
registering callback 5 ... 
MyExceptionType gracefully handled: 
message="Smoked too many Cohibas!" 
MyExceptionType gracefully handled: 
message="Smoked too many Cohibas!" 
MyExceptionType gracefully handled: 
message="Smoked too many Cohibas!" 
MyExceptionType gracefully handled: 
message="Smoked too many Cohibas!" 
MyExceptionType gracefully handled: 
message="Smoked too many Cohibas!" 

Process finished with exit code 0