python - 如何从 C 扩展引发 Python 异常

标签 python c exception signals python-c-extension

我想从 C 扩展中引发 KeyboardInterrupt。

在 C 中,我通过以下 + setup.py 创建了一个名为 siginfo 的模块:

static void siginfo_handler(int signum, siginfo_t *siginfo, void *context) {
    printf("got signal from '%d'", siginfo->si_pid);

    //raise(PyExc_KeyboardInterrupt) <--- i want to raise keyboard interrupt here
}

static PyObject * siginfo_register(PyObject *self, PyObject *args) {
    struct sigaction act;
    memset(&act, '\0', sizeof(act));
    act.sa_sigaction = &siginfo_handler;
    act.sa_flags = SA_SIGINFO;
    sigaction(SIGINT, &act, NULL);

    PY_RETURN_NONE;
}

static PyMethodDef SiginfoMethods[] = {
   //blah blah filled out
};
PyMODINIT_FUNC initsiginfo(void) {
   //blah blah filled out
}

在 Python 中:

import siginfo
import os
siginfo.register()

print "talk to me with kill -SIGINT %d" % os.getpid()

try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    print 'got keybaord interrupt'

C 扩展可以很好地捕获 SIGINT,但我不知道如何从中引发 Python 异常以便我可以在 Python 代码中捕获它。

有什么想法吗?

编辑:
我发现我可以通过以下方式引发 KeyboardInterrupt:

PyErr_SetString(PyExc_KeyboardInterrupt, "SIGINT received");

但如果我在信号处理程序中引发它,它确实会出现段错误。

如果它在其他函数中引发,它不会出现错误。

为什么我不能在信号处理程序中引发它?

最佳答案

您只是在收到信号时未处于执行 Python 代码的状态。在引发错误之前,您需要获取 GIL :

static void siginfo_handler(int signum, siginfo_t *siginfo, void *context) {
    printf("got signal from '%d'\n", siginfo->si_pid);
    PyGILState_STATE gstate = PyGILState_Ensure();
    PyErr_SetString(PyExc_KeyboardInterrupt, "SIGINT received");
    PyGILState_Release(gstate);
}

关于python - 如何从 C 扩展引发 Python 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33552393/

相关文章:

python - suds 脚本失败,出现异常异常 : imported schema failed, 找不到记录器 "suds.xsd.sxbasic"的处理程序

python - 如何处理同一张图上多个对象监听motion_notify_event

c - 不被零除的浮点异常

python - 在 Python 回溯中显示更多级别的异常

javascript - Javascript 中的 try...catch 中出现异常

python - Flake8 无法在自定义格式化程序上加载插件 "N8"

python - list 的每个元素都是 True bool 值

c - 何时重新发送带有选择性重复 ARQ 的滑动窗口丢失的 ACK

c - 如何在 CMake 中使用特定的链接脚本(*.lds)?

java - 没有这样的元素异常(exception)吗?