在导入的模块(用swig包装的C++(中使用似乎调用Triangle的函数时,有时会失败。
问题是没有引发Python异常——在出现错误消息字符串后,它退出到终端,并且该函数调用之后的代码没有机会运行。例如:
import useful_module
# Do stuff here
useful_module.funtion_that_includes_call_to_triangle() # This crashes under certain conditions
### cleanup code here not run... outputs error below ###
# Internal error in segmentintersection():
# Topological inconsistency after splitting a segment.
# Please report this bug to jrs@cs.berkeley.edu
# Include the message above, your input data set, and the exact
# command line you used to run Triangle.
我试图用try/except
包围有问题的行,但由于它退出时没有引发错误,所以没有被捕获。
如果在ipython
会话中尝试了上述操作,它也将退出回到终端。
有没有一种方法可以让它退出我的python会话,从而继续我的代码?
目前,我的解决方案是将调用封装在辅助函数中,并使用multiprocessing.Process
将辅助函数作为新进程启动。在我的情况下,可以使用Queues传递和返回数据。传递回由代码引起的异常是很棘手的——我最终用返回队列中的try/except
和put
来包装整个代码块。如果有更好的方法,请留言或回答。
我已经包含了一些实现,以防有用。
类似于:
import multiprocessing as mp
import queue
import useful_module
# A serialisable worker function
def worker(q, other_args):
try:
# Do stuff here with usual try/except/raise
results = useful_module.funtion_that_includes_call_to_triangle()
q.put(results)
except Exception as e:
q.put(e)
q = mp.Queue()
p = mp.Process(target=worker, args=(q, other_args))
p.start()
p.join()
# Get results from worker
try:
results = q.get(block=False)
except queue.Empty:
print('No result. Triangle probably failed!')
# Do failure handling here
else:
# Check if an exception was raised by worker code
if isinstance(results, Exception):
raise results
# Continue as normal
在触发崩溃的情况下,它只会杀死新创建的工作进程,而父python进程仍然存在。