在阻塞的boost c ++方法中,如何在Python中捕获中断信号? [英] How do I catch an Interrupt signal in Python when inside a blocking boost c++ method?

查看:62
本文介绍了在阻塞的boost c ++方法中,如何在Python中捕获中断信号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用C ++编写的工具集,并为Python提供了Boost绑定.

I have a toolset which has been written in C++, and given Boost bindings for Python.

最初,这段代码全部是C ++,我用以下命令捕获了 CTRL + C 中断:

Initially, this code was all C++, and I caught a CTRL+C interrupt with:

signal( SIGINT, signalCallbackHandler );

void signalCallbackHandler(int /*signum*/)
{
    g_myObject->stop();
}

这很好.

但是,现在我已经添加了Python绑定,正在使用Python初始化对象.

However, now I've added the Python bindings in, I'm using Python to initialise the objects.

我最初的想法是这样做:

My initial thought was to do it like this:

import signal

def handle_interrupt( signum, frame ) :
    g_myObject.stop()

signal.signal( signal.SIGINT, handle_interrupt )
g_myObject = MyObject()
g_myObject.start()

但是,永远不会调用此信号处理程序.

However, this signal handler is never called.

我应该如何处理这样的中断?我是否需要在C ++中执行此操作,然后从那里调用Python函数?

How should I be handling an interrupt like this? Do I need to do it inside C++, and then call the Python function from there?

推荐答案

您的python信号处理程序未调用,因为python推迟了信号处理程序的执行,直到要执行下一个字节码指令之后-参见

Your python signal handler is not called because python defers execution of signal handlers until after the next bytecode instruction is to be executed - see the library documentation for signal, section 18.8.1.1:

Python信号处理程序不会在低级(C)信号处理程序内执行.相反,低级信号处理程序设置一个标志,该标志告诉虚拟机在以后的位置(例如,在下一个字节码指令处)执行相应的Python信号处理程序.这会产生后果:

A Python signal handler does not get executed inside the low-level (C) signal handler. Instead, the low-level signal handler sets a flag which tells the virtual machine to execute the corresponding Python signal handler at a later point(for example at the next bytecode instruction). This has consequences:

  • 捕获由C代码中的无效操作引起的同步错误(如 SIGFPE SIGSEGV )几乎没有意义.Python将从信号处理程序返回到C代码,这很可能再次引发相同的信号,从而导致Python显然挂起.从Python 3.3开始,您可以使用 faulthandler 模块报告同步错误.
  • 一个纯粹用C实现的长时间运行的计算(例如,在大文本正文上进行正则表达式匹配)可以在任意时间不中断地运行,而不管接收到任何信号.计算完成后,将调用Python信号处理程序.
  • It makes little sense to catch synchronous errors like SIGFPE or SIGSEGV that are caused by an invalid operation in C code. Python will return from the signal handler to the C code, which is likely to raise the same signal again, causing Python to apparently hang. From Python 3.3 onwards, you can use the faulthandler module to report on synchronous errors.
  • A long-running calculation implemented purely in C (such as regular expression matching on a large body of text) may run uninterrupted for an arbitrary amount of time, regardless of any signals received. The Python signal handlers will be called when the calculation finishes.

原因是信号可以在任何时间到达,可能会在执行python指令的一半时间到达.VM开始执行信号处理程序并不安全,因为VM处于未知状态.因此,由python安装的实际信号处理程序仅设置一个标志,告诉VM在当前指令完成后调用信号处理程序.

The reason for this is that a signal can arrive at any time, potentially half way through the execution of a python instruction. It would not be safe for the VM to begin executing the signal handler, because the VM is in an unknown state. Therefore, the actual signal handler installed by python merely sets a flag telling the VM to call the signal handler after the current instruction is complete.

如果信号在执行C ++函数期间到达,则信号处理程序将设置标志并返回到C ++函数.

If the signal arrives during execution of your C++ function, then the signal handler sets the flag and returns back to your C++ function.

如果信号处理程序的主要目的是允许C ++函数被中断,那么我建议您省去Python信号处理程序,并安装一个C ++信号处理程序,该程序设置一个触发C ++代码提前退出的标志(大概返回一个表明它已被中断的值).

If the main purpose of the signal handler is to allow the C++ function to be interrupted, then I suggest you dispense with the Python signal handler and install a C++ signal handler that sets a flag which triggers an early exit in your C++ code (presumably returning a value that indicates it was interrupted).

无论您是从python,C ++还是其他绑定中调用代码,该方法都将允许您使用相同的代码.

That approach would allow you to use the same code regardless of whether you are calling your code from python, C++ or perhaps another binding.

这篇关于在阻塞的boost c ++方法中,如何在Python中捕获中断信号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆