在似乎调用 Triangle 的导入模块(用 swig 包裹的 C++)中使用函数时,它有时会失败。
问题是没有引发 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 [email protected]
# Include the message above, your input data set, and the exact
# command line you used to run Triangle.
我试图用
try/except
包围违规行,但是当它退出而不引发错误时,它没有被捕获。
如果在
ipython
会话中尝试上述操作,它也会退出回到终端。
有没有办法让我在退出 python 会话时捕获它,以便我的代码继续?
现在,我的解决方案是将调用包装在辅助函数中,并使用
multiprocessing.Process
将辅助函数作为新进程启动。在我的案例中,可以使用队列传递和返回数据。传回由代码引起的异常很棘手 - 我最终用 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
在触发crash的情况下,只会kill掉新创建的worker进程,python父进程存活。
您的代码导致错误:
p = mp.Process(target=readBT, args=(q))
File "/usr/lib/python3.9/multiprocessing/process.py", line 91, in __init__
self._args = tuple(args)
TypeError: 'Queue' object is not iterable
在“p = mp.Process(target=worker, args=(q))”
我错过了什么吗?