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

标签 python c++ boost

我有一个用 C++ 编写的工具集,并为 Python 提供了 Boost 绑定(bind)。​​

最初,这段代码都是 C++,我用 CTRL+C 中断了:

signal( SIGINT, signalCallbackHandler );

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

这很好用。

但是,现在我已经添加了 Python 绑定(bind),我正在使用 Python 来初始化对象。

我最初的想法是这样做:

import signal

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

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

但是,此信号处理程序从未被调用。

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

最佳答案

您的 python 信号处理程序未被调用,因为 python 将信号处理程序的执行推迟到下一个字节码指令执行之后 - 参见 the library documentation for signal, section 18.8.1.1 :

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:

  • 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在当前指令完成后调用信号处理程序。

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

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

无论您是从 Python、C++ 还是其他绑定(bind)调用您的代码,该方法都允许您使用相同的代码。

关于python - 在阻塞的 boost c++ 方法中,如何在 Python 中捕获中断信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39930722/

相关文章:

python - python/nautilus 脚本组合的奇怪字符编码问题

c++ - 使用 std::equal 和命名空间时出现 "No match operator=="错误

c++ - 生成多个 std::thread 并重用它

c++ - boost asio 中具有异步功能的坏字符

c++ - CMake 无法找到 BOOST 库

python - 如何在一行上一次打印一个字符?

python - 名称错误 : name 'sklearn' is not defined

python - 使用多处理模块的脚本不会终止

c++ - 我可以在模板参数中声明一个 constexpr lambda 吗?

c++ - Boost - 仅当大小匹配时反序列化数组