Nathaniel Smith added the comment:
It turns out that this bug is more general than signal.pause, and has caused
problems for a few different people:
https://github.com/dabeaz/curio/issues/118#issuecomment-287735781
https://github.com/dabeaz/curio/issues/118#issuecomment-287798241
https://github.com/dabeaz/curio/issues/118#issuecomment-287887843
The basic problem is that CPython's signal handling strategy on Unix-likes
assumes that if a signal is delivered to the process at a time when the main
thread is blocked in a syscall, then that syscall will promptly exit with
EINTR. So for example, time.sleep has some clever code on Windows to make it
interruptible with control-C, but on Unix we assume that the kernel will break
the sleep for us.
The problem with this is that POSIX only guarantees that *some* thread will
receive the signal -- not necessarily the main thread. In practice it seems
like most implementations do deliver most signals to the main thread or CPython
wouldn't have gotten away with this for as long as it has, but in particular it
seems like Linux is happy to deliver SIGCHLD to random other threads. So the
C-level signal handler runs in whatever thread, it sets the flag for the main
thread to run the Python-level signal handler... and then the main thread sits
there blocked in sleep() or select() or pause() or whatever, and never checks
the flag.
A simple solution would be to make sure signals are always delivered to the
main thread, by adjusting the C-level signal handler to do something like:
if (current_thread != main_thread) {
pthread_kill(main_thread, sig_num);
return;
}
----------
nosy: +njs
title: signal.pause() doesn't wake up on SIGCHLD in non-main thread ->
signal.pause() and signal handlers don't react to SIGCHLD in non-main thread
versions: +Python 3.6, Python 3.7
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue21895>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com