当前位置: 首页 > 面试题库 >

Cython,Python和KeyboardInterrupt被忽略

常英资
2023-03-14
问题内容

有没有一种方法可以Ctrl+C基于Cython扩展中嵌入的循环来中断()Python脚本

我有以下python脚本:

def main():

    # Intantiate simulator
    sim = PySimulator()
    sim.Run()

if __name__ == "__main__":
    # Try to deal with Ctrl+C to abort the running simulation in terminal
    # (Doesn't work...)
    try:
        sys.exit(main())
    except (KeyboardInterrupt, SystemExit):
        print '\n! Received keyboard interrupt, quitting threads.\n'

这会运行一个循环,该循环是C ++
Cython扩展的一部分。然后,在按Ctrl+C的同时,将KeyboardInterrupt引发,但将其忽略,并且程序将继续进行直到模拟结束。

我发现的解决方法是通过捕获SIGINT信号来处理扩展中的异常:

#include <execinfo.h>
#include <signal.h>

static void handler(int sig)
{
  // Catch exceptions
  switch(sig)
  {
    case SIGABRT:
      fputs("Caught SIGABRT: usually caused by an abort() or assert()\n", stderr);
      break;
    case SIGFPE:
      fputs("Caught SIGFPE: arithmetic exception, such as divide by zero\n",
            stderr);
      break;
    case SIGILL:
      fputs("Caught SIGILL: illegal instruction\n", stderr);
      break;
    case SIGINT:
      fputs("Caught SIGINT: interactive attention signal, probably a ctrl+c\n",
            stderr);
      break;
    case SIGSEGV:
      fputs("Caught SIGSEGV: segfault\n", stderr);
      break;
    case SIGTERM:
    default:
      fputs("Caught SIGTERM: a termination request was sent to the program\n",
            stderr);
      break;
  }
  exit(sig);

}

然后 :

signal(SIGABRT, handler);
signal(SIGFPE,  handler);
signal(SIGILL,  handler);
signal(SIGINT,  handler);
signal(SIGSEGV, handler);
signal(SIGTERM, handler);

我不能通过Python或至少从Cython进行这项工作吗?当我要在Windows / MinGW下移植我的扩展程序时,我希望有一些不特定于Linux的东西。


问题答案:

您必须定期检查未决信号,例如,在模拟循环的第N次迭代中:

from cpython.exc cimport PyErr_CheckSignals

cdef Run(self):
    while True:
        # do some work
        PyErr_CheckSignals()

PyErr_CheckSignals将运行与信号模块一起安装的信号处理程序(KeyboardInterrupt必要时包括升高)。

PyErr_CheckSignals速度非常快,可以经常调用它。请注意,应该从主线程调用它,因为Python在主线程中运行信号处理程序。从辅助线程调用它无效。

说明

由于信号是在不可预测的时间异步传递的,因此直接从信号处理程序运行任何有意义的代码是有问题的。因此,Python将传入的信号排队。稍后将其作为解释器循环的一部分进行处理。

如果您的代码已完全编译,则解释器循环将永远不会执行,并且Python没有机会检查和运行排队的信号处理程序。



 类似资料:
  • 问题内容: 我正在运行以下简单代码: 但是当我运行它时,它会打印 实际上python线程会忽略我的+键盘中断而无法打印。为什么?此代码有什么问题? 问题答案: 尝试 没有对的调用,主要过程是过早地跳出该块,因此不会被捕获。我的第一个想法是使用,但这似乎阻塞了主进程(忽略KeyboardInterrupt),直到完成。 导致线程在主进程结束时终止。

  • 问题内容: 我正在尝试2种方法来阻止无限循环运行: supervisor_1 :任务编程取消 Supervisor_2 :使用Ctrl + C停止任务 虽然 supervisor_2 不会引发中断时,在任何错误,我不能让 supervisor_1 从得到。知道为什么吗? 这是代码: @update : 感谢@Gerasimov,这是一个可以解决此问题的版本,但仍会不时在KeyboardInterr

  • 问题内容: 我正在编写一个程序,通过pickle模块缓存一些结果。目前发生的情况是,如果在执行操作时按ctrl-c,则会被打断,从而导致文件损坏(即仅部分写入,因此无法再次进行编辑)。 有没有办法使代码块或通常的代码块不间断?我当前的解决方法如下所示: 如果操作被中断,重新启动该操作似乎很愚蠢,所以我正在寻找一种推迟中断的方法。我该怎么做呢? 问题答案: 将函数放在线程中,然后等待线程完成。 除非

  • 我正在使用RestEasy、Jboss 7和EJB 3.1。我正在创建一个以JSON格式返回数据的RESTful Web服务。 问题是我在一个实体上有一个关系,这会在序列化期间导致无限递归。我尝试使用Jackson的和annotation来解决这个问题,但似乎它们被完全忽略了,无限递归仍在发生。 这是我的用户类: 这是我角色课的一部分: 我在某处读到过,我应该用我的应用程序注册Jackson,以便

  • 本文向大家介绍cython 包装DLL:从C ++到Cython到Python,包括了cython 包装DLL:从C ++到Cython到Python的使用技巧和注意事项,需要的朋友参考一下 示例 这展示了一个用Cython包装C ++ dll的简单例子。它将涵盖以下主要步骤: 使用Visual Studio使用C ++创建示例DLL。 用Cython包裹DLL,以便可以在Python中调用它。

  • 本文向大家介绍容易被忽略的Python内置类型,包括了容易被忽略的Python内置类型的使用技巧和注意事项,需要的朋友参考一下 Python中的内置类型是我们开发中最常见的,很多人都能熟练的使用它们。 然而有一些内置类型确实不那么常见的,或者说往往会被我们忽略,所以这次的主题就是带领大家重新认识这些“不同寻常”的内置类型。 (注意:本文基于python3,不会包含任何python2相关内容) fr