允许CtrlC中断python Cextension

2024-06-17 08:36:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我在(自制的)基于C的python扩展中运行一些计算量很大的模拟。有时我会搞错东西,想终止模拟。但是,Ctrl-C似乎没有任何效果(除了在屏幕上打印^C),所以我不得不使用kill或系统监视器来终止进程。在

据我所见,python只是等待C扩展完成,而在这段时间内并没有真正与它通信。在

有没有办法让它成功?在

更新:主要答案(针对我的具体问题)是: 1重写代码以定期将控制权传递回调用者(下面回答Allowing Ctrl-C to interrupt a python C-extension),或者 2使用PyErr_CheckSignals()(下面回答https://stackoverflow.com/a/33652496/423420


Tags: to答案代码屏幕进程系统监视器kill
3条回答

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

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

continuation passing style可能与理解有关,作为一种编程风格。。。在

However, Ctrl-C doesn't seem to have any effect

^{} in the shell sends ^{} to the foreground process grouppython接收到信号时用C代码设置一个标志。如果您的C扩展在主线程中运行,那么不会运行任何Python信号处理程序(因此您不会在Ctrl-C上看到KeyboardInterrupt异常),除非您调用检查标志的^{}(这意味着:它不应该减慢速度),并在必要时运行Python信号处理程序,或者如果您的模拟允许Python代码执行(例如。,如果模拟使用Python回调)。如果扩展在后台线程中运行,那么释放GIL就足够了(允许Python代码在主线程中运行,从而使信号处理程序能够运行)。在

相关:Cython, Python and KeybordInterrupt ingored

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解释器。在

相关问题 更多 >