[Python-Dev] Signals, threads, blocking C functions
rhamph at gmail.com
Tue Sep 12 06:05:38 CEST 2006
On 9/11/06, Gustavo Carneiro <gjcarneiro at gmail.com> wrote:
> On 9/11/06, Adam Olsen <rhamph at gmail.com> wrote:
> > This much would allow a GUI's poll loop to wake up when there is a
> > signal, and give control back to the python main loop, which could
> > then read off the signals and queue up their handler functions.
> I like this approach. Not only we would get a poll-able file
> descriptor to notify a GUI main loop when signals arrive, we'd also
> avoid the lack of async safety in Py_AddPendingCall /
> Py_MakePendingCalls which affects _current_ Python code.
> Note that the file descriptor of the read end of the pipe has to
> become a public Python API so that 3rd party extensions may poll it.
> This is crucial.
Yeah, so long as Python still does the actual reading.
> > The only problem is when there is no GUI poll loop. We don't want
> > python to have to poll the fd, we'd rather it just check a variable.
> > Is it possible to set/clear a flag in a sufficiently portable
> > (reentrant-safe, non-blocking, thread-safe) fashion?
> It's simple. That pipe file descriptor has to be changed to
> non-blocking mode in both ends of the pipe, obviously, with fcntl.
> Then, to find out whether a signal happened or not we modify
> PyErr_CheckSignals() to try to read from the pipe. If it reads bytes
> from the pipe, we process the corresponding python signal handlers or
> raise KeyboardInterrupt. If the read() syscall returns zero bytes
> read, we know no signal was delivered and move on.
Aye, but my point was that a syscall is costly, and we'd like to avoid
it if possible.
We'll probably have to benchmark it though, to find out if it's worth
> The only potential problem left is that, by changing the pipe file
> descriptor to non-blocking mode we can only write as many bytes to it
> without reading from the other side as the pipe buffer allows. If a
> large number of signals arrive very quickly, that buffer may fill and
> we lose signals. But I think the default buffer should be more than
> enough. And normally programs don't receive lots of signals in a
> small time window. If it happens we may lose signals, but that's very
> rare, and who cares anyway.
Indeed, we need to document very clearly that:
* Signals may be dropped if there is a burst
* Signals may be delayed for a very long time, and if you replace a
previous handler your new handler may get signals intended for the old
Adam Olsen, aka Rhamphoryncus
More information about the Python-Dev