In typical server applications you can use signalfd to handle signals like receiving data from a client instead of polling. I think on older versions of Linux you could use a trick where you write a single byte to a pipe in the signal handler to achieve a similar effect.
Right which is why you don't actually do much of anything in the signal handler except save that it happened somewhere to be processed by your application later.
Uh, that Examples section calls print inside the signal handler. Python's IO stack is non-reentrant. I hope nobody follows these examples and gets exceptions at runtime because of it.
"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)"
The low-level C handler set the flag then returns. Only some time later does the Python run-time call the associated Python handler that you see in the Examples section.
In this case that's before the next bytecode executes. The write syscall gets interrupted and returns EINTR, then cpython checks what signal was caught and executes the signal handler, before trying to do the remaining write:
Except the standard logger route my isn’t signal safe, nor much of the basic library routines one would want to use!
The only sane solution is to block/mask all signals, perhaps polling for them if really needed. Anything else is on the path to insanity.