import threading import time class ThM(object): """ThM (ThreadManager) Handles very simple thread operations: Creating single-shot threads -> ThM.run(...) Creating 'looping per interval' threads -> ThM.run(...) with loop set to True Stopping looping threads based on name -> ThM.stop_loop(...) Joining all threads into the calling thread ThM.joinall() Removing stopped threads from 'running_threads' - > ThM.free_dead() The class has been designed for very simple operations, mainly for programs that need "workers" that mindlessly loop over a function. NOTE: Locks,Events,Semaphores etc. have not been taken into consideration and may cause unexpected behaviour if used! """ running_threads = [] @classmethod def run(cls,targetfunc,thname,loop,interval,arglist=[]): """Statrs a new thread and appends it to the running_threads list along with the specified values. Loop and interval needs to be specified even if you dont want it to loop over. This is to avoid lot of keyword arguments and possible confusion. Example of starting a looping thread: ThM.run(function,"MyThreadName",True,0.5,[1,2,"StringArguemnt"]) To stop it, use: ThM.stop_loop("MyThreadName") Note, a stopped thread cannot be started again! Example of a single-shot thread: ThM.run(function,"ThreadName",False,0.5,[1,2,"StringArgument"]) """ th = threading.Thread(target=cls._thread_runner_,args=(targetfunc,thname,interval,arglist)) th.setDaemon(True) cls.running_threads.append([th,thname,loop]) th.start() @classmethod def free_dead(cls): """Removes all threads that return FALSE on isAlive() from the running_threads list """ for th in cls.running_threads[:]: if th[0].isAlive() == False: cls.running_threads.remove(th) @classmethod def stop_loop(cls,threadname): """Stops a looping function that was started with ThM.run(...)""" for i,thlis in enumerate(cls.running_threads): if thlis[1] == threadname: cls.running_threads[i][2] = False break @classmethod def joinall(cls): """Joins all the threads together into the calling thread.""" for th in cls.running_threads[:]: while th[0].isAlive(): time.sleep(0.1) th[0].join() # print "Thread:",th[1],"joined","isalive:",th[0].isAlive() --- Debug stuff @classmethod def get_all_params(cls): """Returns parameters from the running_threads list for external manipulation""" for thli in cls.running_threads: yield(thli[0],thli[1],thli[2]) #This method is only intended for threads started with ThM ! @classmethod def _thread_runner_(cls,targetfunc,thname,interval,arglist): """Internal function handling the running and looping of the threads Note: threading.Event() has not been taken into consideration and neither the other thread managing objects (semaphores, locks, etc.)""" indx=0 for thread in cls.running_threads[:]: if thname == thread[1]: break indx+=1 targetfunc(*arglist) while cls.running_threads[indx][2] == True: targetfunc(*arglist) if interval != 0: time.sleep(interval)