[Tutor] Multi-Threading and KeyboardInterrupt

Matthew Strax-Haber strax-haber.m at neu.edu
Wed Jun 10 05:01:33 CEST 2009


Hey everyone,

I hope one of you can help me with this. This is my first foray into  
multi-threaded programming. I have tried to boil my code down to it's  
simplest demonstrative form.

My program runs interactively by allowing the user to directly  
interact with the python prompt. This program has a runAll() method  
that runs a series of subprocesses with a cap on how many instances  
are running at a time. My intent is to allow the user to use Ctrl-C to  
break these subprocesses. Note that while not reflected in the demo  
below, each subprocess needs to be able to run clean-up code before  
shutting down (in single-threaded mode I just wrap in try-finally).  
When I run DB.py, and interrupt it with Ctrl-C, things do not run so  
cleanly. Please let me know what I can change to make this work  
properly. My intent is to have the following output:

'key interrupt 1'
'key interrupt 2'
'key interrupt 3'
'key interrupt 4'
'********* stopped midway ********'

Here is the code for a demo:
##############################################################################
DB.py (run this):
##############################################################################
#!/usr/bin/env python

from subprocess	import Popen
from threading	import Thread, BoundedSemaphore

RUN_PERMISSION	= BoundedSemaphore(3)

def runSingle(i):
	with RUN_PERMISSION:
		Popen(['./Sub.py', str(i)]).wait()
		
def runAll():
	workers = [ Thread(target = runSingle, args = [i])
			for i in xrange(RUN_PERMISSION._initial_value + 1) ]
	try:
		for w in workers:
			w.start()
	except KeyboardInterrupt:
		## This should be shown on a KeyboardInterrupt
		print '********* stopped midway ********'
	for w in workers:
		w.join()
			
runAll()
##############################################################################
Sub.py (called by DB.py):
##############################################################################
#!/usr/bin/env python

import sys, time

try:
	while True: pass
except KeyboardInterrupt:
	print 'key interrupt %s' % sys.argv[1]
	raise
##############################################################################


More information about the Tutor mailing list