Problem: using signal.alarm() to stop a run-away os.system() command

Jp Calderone exarkun at divmod.com
Fri May 27 15:42:44 EDT 2005


On 27 May 2005 12:09:39 -0700, mkent at webmd.net wrote:
>I'm trying to use signal.alarm to stop a run-away os.system command.
>Can anyone exlain the following behavior?
>
>Given following the trivial program:
>
>import os
>import signal
>
>def timeoutHandler(signum, frame):
>    print "Timeout"
>    raise ValueError
>
>
>signal.signal(signal.SIGALRM, timeoutHandler)
>signal.alarm(5)
>
>os.system("yes")
>
>signal.alarm(0)
>
>
>What I expect is that the Linux/UNIX 'yes' command (which runs until
>terminated) would be stopped after 5 seconds, when the timeoutHandler
>is called, thus raising a ValueError and terminating this example
>program.  Instead, the 'yes' command run until it is terminated (by,
>say, a kill command), at which time the timeoutHandler is called.  In
>other words, the running of the 'yes' command acts like it is blocking
>the SIGALRM signal until it terminates, at which time the SIGALRM
>signal is raised.  This is quite surprising, and totally defeats my
>ability to catch a run-away process.  Can anyone see what I'm doing
>wrong?

CPython only delivers signals to Python programs in between bytecodes.  Since your program is hanging around in the system(3) call, it isn't executing any bytecode, so CPython never gets an opportunity to deliver the signal.

Try using a pipe (popen() or the new subprocess module) and select() with a timeout of 5.

Jp



More information about the Python-list mailing list