<s> """<STR_LIT>""" <EOL> __version__ = '<STR_LIT>' <EOL> import sys , threading , os <EOL> class ThreadPool ( dict ) : <EOL> pools = [ ] <EOL> def __init__ ( self , worker , max_threads , * args , ** kwargs ) : <EOL> dict . __init__ ( self ) <EOL> self . jobLock = threading . Lock ( ) <EOL> self . jobQueue = [ ] <EOL> self . worker = worker <EOL> self . threads = [ ] <EOL> self . max_threads = max_threads <EOL> self . args = args <EOL> self . kwargs = kwargs <EOL> self . pools . append ( self ) <EOL> def append ( self , job ) : <EOL> self . jobLock . acquire ( ) <EOL> counter = <NUM_LIT:0> <EOL> try : <EOL> self . jobQueue . append ( job ) <EOL> unlock_workers = len ( self . jobQueue ) <EOL> for event in self . itervalues ( ) : <EOL> if not event . isSet ( ) : <EOL> event . set ( ) <EOL> counter += <NUM_LIT:1> <EOL> if counter == unlock_workers : <EOL> break <EOL> finally : <EOL> self . jobLock . release ( ) <EOL> if counter == <NUM_LIT:0> and len ( self . threads ) < self . max_threads : <EOL> self . add_thread ( ) <EOL> self . start ( ) <EOL> def add_thread ( self ) : <EOL> self . jobLock . acquire ( ) <EOL> try : <EOL> thread = self . worker ( self , * self . args , ** self . kwargs ) <EOL> self . threads . append ( thread ) <EOL> self [ id ( thread ) ] = threading . Event ( ) <EOL> finally : <EOL> self . jobLock . release ( ) <EOL> def start ( self ) : <EOL> for thread in self . threads : <EOL> if not thread . isAlive ( ) : <EOL> thread . start ( ) <EOL> def exit ( self ) : <EOL> self . jobLock . acquire ( ) <EOL> try : <EOL> del self . jobQueue [ : ] <EOL> for thread in self . threads : <EOL> thread . quit = True <EOL> self [ id ( thread ) ] . set ( ) <EOL> finally : <EOL> self . jobLock . release ( ) <EOL> def is_idle ( self ) : <EOL> self . jobLock . acquire ( ) <EOL> try : <EOL> idle = len ( self . jobQueue ) == <NUM_LIT:0> <EOL> for thread in self . threads : <EOL> idle = idle and thread . is_idle <EOL> finally : <EOL> self . jobLock . release ( ) <EOL> return idle <EOL> class Thread ( threading . Thread ) : <EOL> timeout = None <EOL> def __init__ ( self , pool ) : <EOL> threading . Thread . __init__ ( self ) <EOL> self . pool = pool <EOL> self . quit = False <EOL> self . is_idle = True <EOL> def run ( self ) : <EOL> while True : <EOL> self . pool . jobLock . acquire ( ) <EOL> if self . quit and not self . pool . jobQueue : <EOL> self . pool . jobLock . release ( ) <EOL> return <EOL> if not self . pool . jobQueue : <EOL> event = self . pool [ id ( self ) ] <EOL> self . pool . jobLock . release ( ) <EOL> event . clear ( ) <EOL> event . wait ( self . timeout ) <EOL> if not event . isSet ( ) and self . timeout != None : <EOL> if self . starve ( ) : return <EOL> continue <EOL> job = self . pool . jobQueue . pop ( <NUM_LIT:0> ) <EOL> self . is_idle = False <EOL> self . pool . jobLock . release ( ) <EOL> self . do ( job ) <EOL> self . is_idle = True <EOL> def exit ( self ) : <EOL> self . pool . jobLock . acquire ( ) <EOL> try : <EOL> self . quit = True <EOL> if id ( self ) in self . pool : <EOL> self . pool [ id ( self ) ] . set ( ) <EOL> del self . pool [ id ( self ) ] <EOL> if self in self . pool . threads : <EOL> self . pool . threads . remove ( self ) <EOL> finally : <EOL> self . pool . jobLock . release ( ) <EOL> def starve ( self ) : <EOL> pass <EOL> def catch_signals ( ) : <EOL> import signal <EOL> signal . signal ( signal . SIGINT , sig_handler ) <EOL> signal . signal ( signal . SIGTERM , sig_handler ) <EOL> def sig_handler ( signalnum , stack ) : <EOL> import signal <EOL> for pool in ThreadPool . pools : <EOL> pool . exit ( ) <EOL> if signalnum == signal . SIGINT : <EOL> raise KeyboardInterrupt <EOL> if signalnum == signal . SIGTERM : <EOL> raise SystemExit <EOL> def terminate ( ) : <EOL> import signal <EOL> os . kill ( <NUM_LIT:0> , signal . SIGTERM ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> import time <EOL> class Worker ( Thread ) : <EOL> def do ( self , args ) : <EOL> print '<STR_LIT>' , self <EOL> time . sleep ( <NUM_LIT:10> ) <EOL> print '<STR_LIT>' , self <EOL> pool = ThreadPool ( Worker ) <EOL> print '<STR_LIT>' <EOL> [ pool . add_thread ( ) for i in xrange ( <NUM_LIT:5> ) ] <EOL> pool . start ( ) <EOL> print '<STR_LIT>' <EOL> for i in xrange ( <NUM_LIT> ) : <EOL> print '<STR_LIT>' , i <EOL> pool . append ( i ) <EOL> time . sleep ( i % <NUM_LIT:6> ) <EOL> for thread in pool . threads : <EOL> thread . exit ( ) </s>
