且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在阻塞的boost c ++方法中,如何在Python中捕获中断信号?

更新时间:2022-05-10 21:19:56

您的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.