Skip to content
Tech News
← Back to articles

Is it safe to call print in a Python signal handler?

read original more articles
Why This Matters

This article highlights the complexities and potential pitfalls of handling signals in Python, particularly the risks of reentrant calls when using functions like print within signal handlers. Understanding these nuances is crucial for developers aiming to write robust, safe signal-handling code in Python applications, especially in scenarios involving rapid or multiple signals.

Key Takeaways

Is it safe to call print in a Python signal handler?

We learned earlier that because Python has two signal handlers, the onerous restrictions on what functions a signal handler may call do not apply to Python, because CPython does not call the user-supplied Python signal handler inside the low-level C signal handler, where those restrictions do apply, but arranges for it to be called later, when the interpreter is in a consistent state.

We also learned that Python signal handlers are unexpectedly reentrant – if a signal arrives while a Python signal handler is running, the signal handler can be called again in the middle of the first call.

What happens if a signal handler is reentered in the middle of a call to print ? Let's stress-test it by sending ourselves a rapid barrage of signals:

import os , signal , subprocess def sighandler ( _signo , _frame ): print ( "signal received" ) signal . signal ( signal . SIGUSR1 , sighandler ) subprocess . run ( "for x in {1..50}; do kill -USR1 %s ; done" % os . getpid (), shell = True )

Running this program on my machine produced:

File "multiple_signals.py", line 6, in sighandler print("signal received") File "multiple_signals.py", line 6, in sighandler print("signal received") File "multiple_signals.py", line 6, in sighandler print("signal received") [Previous line repeated 2 more times] RuntimeError: reentrant call inside <_io.BufferedWriter name='<stdout>'>