如何在不杀死解释器的情况下中断本机扩展代码?

时间:2014-02-04 10:53:33

标签: python c++ ipython interrupt cython

我正在开发一个项目,该项目将用C ++编写的高性能算法与Python接口相结合。 C ++类和函数通过Cython编译器封装并暴露给Python。

假设我从Python解释器调用一个长时间运行的本机函数(我首选的是IPython)。是否有可能在不杀死解释器的情况下中断或中止该代码的执行?

3 个答案:

答案 0 :(得分:2)

这是使用Ricardo C.建议的multiprocessing的可能实现,

import multiprocessing as mpr
def dangerwrap(f):
  """
  I assume f is, or eventually calls, 
  some external function, like cython wrapped C/C++.
  Also assuming that f returns an
  object and takes no parameters
  """
  event  = mpr.Event()
  q = mpr.Queue()

  def signalling_f():
    q.put(f())
    event.set()

  f_process = mpr.Process(target = signalling_f)
  f_process.start()
  try:
    event.wait()

  except KeyboardInterrupt:
    f_process.terminate()
    f_process.join()
    print "Caught in dangerwrap"
    return None


  print "Exiting normally"
  return q.get()

现在代替,

X = f()

,它不响应键盘中断,调用

X = dangerwrap(f)

将通过键盘中断正常停止。

答案 1 :(得分:1)

好的,我在这里假设您正在尝试运行一些可能遇到麻烦的优化代码(例如,运行时间超过预期),然后您需要将其删除。

我的理解是,在不杀死解释器的情况下停止运行代码是不可能的,因为C / C ++代码将运行Python虚拟机控件的 out 。因此,一种选择是使用标准multiprocessing模块在​​单独的进程中运行代码。

这样做可以让你无缝地来回传递数据它会增加使用任何标准方法杀死新进程的可能性,例如。来自父进程的Process.terminateos.kill ...或您的操作系统提供的任何命令行/图形工具。

答案 2 :(得分:0)

cysignals解决了这个问题。请参阅this answer