@@ -248,6 +248,41 @@ that that were ``malloc()``-ed in another shared library, using data
248
248
structures with incompatible ABIs, and so on. pybind11 is very careful not
249
249
to make these types of mistakes.
250
250
251
+ How can I properly handle Ctrl-C in long-running functions?
252
+ ===========================================================
253
+
254
+ Ctrl-C is received by the Python interpreter, and holds it until the GIL
255
+ is released, so a long-running function won't be interrupted.
256
+
257
+ To interrupt from inside your function, you can use the ``PyErr_CheckSignals() ``
258
+ function, that will tell if a signal has been raised on the Python side. This
259
+ function merely checks a flag, so its impact is negligible. When a signal has
260
+ been received, you can explicitely interrupt execution by throwing an exception
261
+ that gets translated to KeyboardInterrupt (see :doc: `advanced/exceptions `
262
+ section):
263
+
264
+ .. code-block :: cpp
265
+
266
+ class interruption_error: public std::exception {
267
+ public:
268
+ const char* what() const noexcept {
269
+ return "Interruption signal caught.";
270
+ }
271
+ };
272
+
273
+ PYBIND11_MODULE(example, m)
274
+ {
275
+ m.def("long running_func", []()
276
+ {
277
+ for (;;) {
278
+ if (PyErr_CheckSignals() != 0)
279
+ throw interruption_error();
280
+ // Long running iteration
281
+ }
282
+ });
283
+ py::register_exception<interruption_error>(m, "KeyboardInterrupt");
284
+ }
285
+
251
286
Inconsistent detection of Python version in CMake and pybind11
252
287
==============================================================
253
288
0 commit comments