[Python-Dev] Problem with signals in a single threaded application

Ulisses Furquim ulissesf at gmail.com
Tue Jan 23 20:37:09 CET 2007


Hi,

I'm aware of the problems with signals in a multithreaded application,
but I was using signals in a single-threaded application and noticed
something that seemed wrong. Some signals were apparently being lost,
but when another signal came in the python handler for that "lost"
signal was being called.

The problem seems to be inside the signal module. The global variable
is_tripped is incremented every time a signal arrives. Then, inside
PyErr_CheckSignals() (the pending call that calls all python handlers
for signals that arrived) we can return immediately if is_tripped is
zero. If is_tripped is different than zero, we loop through all
signals calling the registered python handlers and after that we zero
is_tripped. This seems to be ok, but what happens if a signal arrives
after we've returned from its handler (or even after we've checked if
that signal arrived) and before we zero is_tripped? I guess we can
have a situation where is_tripped is zero but some Handlers[i].tripped
are not. In fact, I've inserted some debugging output and could see
that this actually happens and then I've written the following test
program to reproduce the problem.

#!/usr/bin/env python2.5

import sys
import os
import time
import signal

def alarm_handler(*args):
        sys.stderr.write('alarmmmmmmmmmmm!\n')

def sigio_handler(*args):
        sys.stderr.write('Entering SIGIO handler\n')
        os.kill(os.getpid(), signal.SIGALRM)
        sys.stderr.write('Leaving SIGIO handler\n')

signal.signal(signal.SIGIO, sigio_handler)
signal.signal(signal.SIGALRM, alarm_handler)

os.kill(os.getpid(), signal.SIGIO)

ini = time.time()
while True :
        if time.time() - ini > 3.0:
                sys.stderr.write('Loop!\n')
                ini = time.time()

When we run this program, the handler for the SIGALRM isn't called
after we return from the  SIGIO handler. We return to our main loop
and print 'Loop!' every 3 seconds aprox. and the SIGALRM handler is
called only when another signal arrives (like when we hit Ctrl-C).

I've read some threads about signals in the archives and I was under
the impression signals should work reliably on single-threaded
applications. Am I right?  I've thought about a way to fix this, but I
don't know what is the current plan for signals support in python, so
what can be done?

Best regards,

-- Ulisses


More information about the Python-Dev mailing list