views:

91

answers:

1

I have a Tkinter GUI running two threads, the main tread for the GUI and a worker thread. The worker thread creates a subprocess using the following code:

myProcess = subprocess.Popen(['python', '-u', 'runTests.py'],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

The file runTests.py does some setup and then runs a unit test file using the following command:

execfile('myUnitTests.py')

The file myUnitTests.py has several unit tests some that take over five minutes to run. From the GUI I click a button to stop running the tests. This in turn makes the worker thread send a signal to stop the subprocess:

myProcess.terminate()

The terminate command does not stop the process right away, it waits until the current unit test finishes running and then it terminates the process? I have tried to use os.kill but I get the same results as with terminate()

Any idea of how can I make my program more responsive so that it kill the subprocess right away?

A: 

The Python documentation [ http://docs.python.org/library/signal.html ] says:

  • Although Python signal handlers are called asynchronously as far as the Python user is concerned, they can only occur between the “atomic” instructions of the Python interpreter. This means that signals arriving during long calculations implemented purely in C (such as regular expression matches on large bodies of text) may be delayed for an arbitrary amount of time.

So if your five-minute unit test is doing "a long calculation implemented purely in C", and your unit test harness installs a handler for SIGTERM, that's your problem. If so, try myProcess.kill instead of myProcess.terminate (or, if you haven't got 2.6, myProcess.send_signal(9)). SIGKILL is uncatchable from user space and should have immediate effect.

Warning: any clean-up actions that are supposed to run on the way out of your unit test framework will not be executed.

Zack