允许Ctrl-C中断python C扩展

Mic*_*erx 12 python linux python-c-api

我在(自制的)基于C的python扩展中运行一些计算量很大的模拟.偶尔我会弄错,想终止模拟.但是,Ctrl-C似乎没有任何效果(除了打印^C到屏幕,所以我必须使用kill或系统监视器终止进程.

据我所知,python只是等待C扩展完成,并且在此期间并没有真正与它通信.

有没有办法让这项工作?

jfs*_*jfs 8

但是,Ctrl-C似乎没有任何效果

Ctrl-C在shell中发送SIGINT到前台进程组.python接收信号时,在C代码中设置一个标志.如果你的C扩展在主线程中运行,那么就不会运行Python信号处理程序(因此你不会看到KeyboardInterrupt异常Ctrl-C)除非你调用PyErr_CheckSignals()它来检查标志(这意味着:它不应该减慢你的速度)并运行Python必要时信号处理程序或模拟允许Python代码执行(例如,如果模拟使用Python回调).如果扩展在后台线程中运行,那么释放GIL就足够了(允许Python代码在主线程中运行,使得信号处理程序能够运行).

相关:Cython,Python和KeybordInterrupt进入


nne*_*neo 7

Python安装了一个信号处理程序SIGINT,只需设置一个由主解释器循环检查的标志.要使此处理程序正常工作,Python解释器必须运行Python代码.

您有几种选择:

  1. 使用Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS来释放C扩展代码周围的GIL.不保存GIL时不能使用任何Python函数,但Python代码(和其他C代码)可能与C线程并行运行(真正的多线程).一个单独的Python线程可以与C扩展一起执行并捕获Ctrl + C信号.
  2. 设置自己的SIGINT处理程序并调用原始(Python)信号处理程序.SIGINT然后,您的处理程序可以执行任何操作来取消C扩展代码并将控制权返回给Python解释器.


Bas*_*tch 0

我会重新设计 C 扩展,这样它们就不会运行很长时间。

因此,将它们分成更基本的步骤(每个步骤运行很短的时间,例如 10 到 50 毫秒),并让这些更基本的步骤由 Python 代码调用。

连续传递风格可能与理解相关,作为一种编程风格......

  • 抱歉,在这种情况下根本不是一个选项:)这是一个具有大量步骤的模拟,速度至关重要。每一步(甚至定期)与 python 交互都会破坏效率。 (7认同)
  • 尝试将这些步骤集中到持续几毫秒的时间中。那么使用 Python 的开销可以忽略不计...... (3认同)