Allowing Ctrl-C to interrupt a python C-extension

后端 未结 4 451
情歌与酒
情歌与酒 2020-12-10 03:20

I\'m running some computationally heavy simulation in (home-made) C-based python extensions. Occasionally I get stuff wrong and would like to terminate a simulation. However

4条回答
  •  执念已碎
    2020-12-10 04:06

    However, Ctrl-C doesn't seem to have any effect

    Ctrl-C in the shell sends SIGINT to the foreground process group. python on receiving the signal sets a flag in C code. If your C extension runs in the main thread then no Python signal handler will be run (and therefore you won't see KeyboardInterrupt exception on Ctrl-C) unless you call PyErr_CheckSignals() that checks the flag (it means: it shouldn't slow you down) and runs Python signal handlers if necessary or if your simulation allows Python code to execute (e.g., if the simulation uses Python callbacks). Here's a code example of an extension module for CPython created using pybind11 suggested by @Matt:

    PYBIND11_MODULE(example, m)
    {
        m.def("long running_func", []()
        {
            for (;;) {
                if (PyErr_CheckSignals() != 0)
                    throw py::error_already_set();
                // Long running iteration
            }
        });
    }
    

    If the extension runs in a background thread then it is enough to release GIL (to allow Python code to run in the main thread that enables the signal handlers to run). PyErr_CheckSignals() always returns 0 in a background thread.

    Related: Cython, Python and KeybordInterrupt ingored

提交回复
热议问题